diff options
Diffstat (limited to 'arch')
79 files changed, 17287 insertions, 767 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 36586dba6fa..275ac0dd1e8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -73,6 +73,10 @@ config KTIME_SCALAR bool default y +config KTIME_SCALAR + bool + default y + config HAVE_TCM bool select GENERIC_ALLOCATOR @@ -933,9 +937,11 @@ config ARCH_U8500 select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP select ARCH_REQUIRE_GPIOLIB + select HAVE_CLK select ARCH_HAS_CPUFREQ select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 + select NOMADIK_GPIO help Support for ST-Ericsson's Ux500 architecture @@ -1756,7 +1762,9 @@ source "mm/Kconfig" config FORCE_MAX_ZONEORDER int "Maximum zone order" if ARCH_SHMOBILE range 11 64 if ARCH_SHMOBILE + depends on SA1111 || UX500_SOC_DB8500 default "9" if SA1111 + default "12" if UX500_SOC_DB8500 default "11" help The kernel memory allocator divides physically contiguous memory @@ -2071,6 +2079,13 @@ config KEXEC initially work for you. It may help to enable device hotplugging support. +config CRASH_SWRESET + bool "Perform a software reset at a panic (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on KEXEC + help + If no crash kernel has been loaded, perform a SW reset as plan B. + config ATAGS_PROC bool "Export atags in procfs" depends on KEXEC diff --git a/arch/arm/configs/u8500_android_defconfig b/arch/arm/configs/u8500_android_defconfig new file mode 100644 index 00000000000..62d360df4f4 --- /dev/null +++ b/arch/arm/configs/u8500_android_defconfig @@ -0,0 +1,344 @@ +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB=y +CONFIG_PROFILING=y +CONFIG_BOOTTIME=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_BLKDEV_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SGI_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_ARCH_U8500=y +CONFIG_UX500_SOC_DB8500=y +CONFIG_MACH_HREFV60=y +CONFIG_MACH_U8520=y +CONFIG_MACH_SNOWBALL=y +CONFIG_MACH_U9540=y +CONFIG_UX500_GPIO_KEYS=y +CONFIG_DBX500_PRCMU_DEBUG=y +CONFIG_DB8500_PWR_TEST=y +# CONFIG_UX500_USECASE_GOVERNOR is not set +CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_VSYNC=y +CONFIG_DB8500_MLOADER=y +CONFIG_PCCARD=y +# CONFIG_PCMCIA is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=2 +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_CMDLINE="root=/dev/ram0 init=init rw console=ttyAMA2,115200n8 mem=256M initrd=0x800000,72M" +CONFIG_KEXEC=y +CONFIG_CRASH_SWRESET=y +CONFIG_CRASH_DUMP=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_IDLE=y +CONFIG_U8500_CPUIDLE_DEEPEST_STATE=2 +CONFIG_UX500_CPUIDLE_DEBUG=y +CONFIG_FPE_NWFPE=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_WAKELOCK=y +CONFIG_PM_RUNTIME=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_LRO is not set +CONFIG_IPV6=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_ULOG=y +CONFIG_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_PHONET=y +CONFIG_NET_SCHED=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_REG_DEBUG=y +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_REGULATOR=y +CONFIG_RFKILL_GPIO=y +CONFIG_NET_9P=y +CONFIG_CAIF=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_STANDALONE is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=73728 +CONFIG_AB8500_PWM=y +CONFIG_SENSORS_BH1780=y +CONFIG_STE_TRACE_MODEM=y +CONFIG_DISPDEV=y +CONFIG_U8500_SIM_DETECT=y +CONFIG_STM_TRACE=y +CONFIG_STM_DEFAULT_MASTERS_MODES=0x20 +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_UEVENT=y +CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_CAIF_TTY=m +CONFIG_CAIF_HSI=m +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y +CONFIG_PPP=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_ASYNC=y +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_NOMADIK_SKE=y +CONFIG_KEYBOARD_TC3589X=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_CYTTSP_CORE=y +CONFIG_TOUCHSCREEN_CYTTSP_SPI=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_AB8500_ACCDET=y +CONFIG_INPUT_AB8500_PONKEY=y +CONFIG_INPUT_UINPUT=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_AMBA_PL011_CLOCK_CONTROL=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_NOMADIK=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_NOMADIK=y +CONFIG_SPI=y +CONFIG_SPI_PL022=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_TC3589X=y +CONFIG_GPIO_AB8500=y +CONFIG_POWER_SUPPLY=y +CONFIG_AB8500_BM=y +CONFIG_SENSORS_AB8500=y +CONFIG_SENSORS_DBX500=y +CONFIG_SENSORS_LSM303DLH=y +CONFIG_SENSORS_LSM303DLHC=y +CONFIG_SENSORS_L3G4200D=y +CONFIG_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_UX500_WATCHDOG_DEBUG=y +CONFIG_MFD_TC3589X=y +CONFIG_AB5500_CORE=y +CONFIG_AB8500_CORE=y +CONFIG_MFD_DB8500_PRCMU=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_REGULATOR_AB8500=y +CONFIG_REGULATOR_DB8500_PRCMU=y +CONFIG_REGULATOR_AB8500_DEBUG=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_VIDEO_DEV=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_RADIO_CG2900=y +CONFIG_GPU_MALI=y +CONFIG_FB=y +CONFIG_FB_MCDE=y +CONFIG_MCDE_FB_AVOID_REALLOC=y +CONFIG_MCDE_DISPLAY_GENERIC_DSI=y +CONFIG_MCDE_DISPLAY_SAMSUNG_S6D16D0=y +CONFIG_MCDE_DISPLAY_SONY_ACX424AKP_DSI=y +CONFIG_MCDE_DISPLAY_AV8100=y +CONFIG_MCDE_DISPLAY_HDMI_FB_AUTO_CREATE=y +CONFIG_AV8100_HWTRIG_I2SDAT3=y +CONFIG_FB_B2R2=y +CONFIG_B2R2_PLUG_CONF=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_UX500=y +CONFIG_SND_SOC_UX500_AB5500=y +CONFIG_SND_SOC_UX500_AB8500=y +CONFIG_SND_SOC_UX500_CG29XX=y +CONFIG_SND_SOC_UX500_AV8100=y +CONFIG_HIDRAW=y +CONFIG_USB=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_MON=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_UX500=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_G_ANDROID=y +CONFIG_AB8500_USB=y +CONFIG_MMC=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_BLOCK_MINORS=32 +# CONFIG_MMC_BLOCK_BOUNCE is not set +CONFIG_MMC_ARMMMCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_LM3530=y +CONFIG_LEDS_LP5521=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_SWITCH=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AB=y +CONFIG_RTC_DRV_AB8500=y +CONFIG_DMADEVICES=y +CONFIG_STE_DMA40=y +CONFIG_STAGING=y +CONFIG_AB5500_SIM=y +CONFIG_CG2900=y +CONFIG_CG2900_CHIP=y +CONFIG_STLC2690_CHIP=y +CONFIG_CG2900_UART=y +CONFIG_CG2900_AUDIO=y +CONFIG_CG2900_TEST=y +CONFIG_BT_CG2900=y +CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_LOGGER=y +CONFIG_ANDROID_RAM_CONSOLE=y +CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_CW1200=m +CONFIG_CW1200_USE_GPIO_IRQ=y +CONFIG_CW1200_DEBUGFS=y +CONFIG_U8500_MMIO=y +CONFIG_U8500_CM=y +CONFIG_U8500_FLASH=y +CONFIG_HSEM_U8500=y +CONFIG_MODEM_U8500=y +CONFIG_U8500_SHRM=y +CONFIG_U8500_SHRM_MODEM_SILENT_RESET=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_QUOTA=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS4_FS=m +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HFS_FS=m +CONFIG_BEFS_FS=m +CONFIG_CRAMFS=m +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_ROMFS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +CONFIG_9P_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_DEBUG_INFO=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_FUNCTION_TRACER=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_USER=y +CONFIG_KEYS=y +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_TWOFISH=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DEV_UX500=y +CONFIG_CRYPTO_DEV_UX500_HASH=y +CONFIG_CRC7=y +CONFIG_LIBCRC32C=m diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 7e84f453e8a..30e88eb8985 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -1,117 +1,322 @@ CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB=y +CONFIG_PROFILING=y +CONFIG_BOOTTIME=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_BLKDEV_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SGI_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_DEFAULT_DEADLINE=y CONFIG_ARCH_U8500=y +CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_HREFV60=y +CONFIG_MACH_U8520=y CONFIG_MACH_SNOWBALL=y -CONFIG_MACH_U5500=y +CONFIG_MACH_U9540=y +CONFIG_MACH_U8500_SNOWBALL=y CONFIG_MACH_UX500_DT=y +CONFIG_UX500_GPIO_KEYS=y +CONFIG_DBX500_PRCMU_DEBUG=y +CONFIG_DB8500_PWR_TEST=y +CONFIG_DB8500_MLOADER=y +CONFIG_PCCARD=y +# CONFIG_PCMCIA is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y +CONFIG_SCHED_MC=y CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y CONFIG_AEABI=y -CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" +# CONFIG_OABI_COMPAT is not set +CONFIG_HIGHMEM=y +CONFIG_CMDLINE="root=/dev/ram0 init=init rw console=ttyAMA2,115200n8 mem=256M initrd=0x800000,72M" +CONFIG_KEXEC=y +CONFIG_CRASH_SWRESET=y +CONFIG_CRASH_DUMP=y CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_IDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_PM_RUNTIME=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_LRO is not set +CONFIG_IPV6=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_ULOG=y +CONFIG_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP6_NF_IPTABLES=y CONFIG_PHONET=y -# CONFIG_WIRELESS is not set +CONFIG_NET_SCHED=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_REG_DEBUG=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_NET_9P=y CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_STANDALONE is not set +CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_SIZE=73728 CONFIG_AB8500_PWM=y CONFIG_SENSORS_BH1780=y +CONFIG_STE_TRACE_MODEM=y +CONFIG_DISPDEV=y +CONFIG_U8500_SIM_DETECT=y +CONFIG_STM_TRACE=y +CONFIG_STM_DEFAULT_MASTERS_MODES=0x20 +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_UEVENT=y CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_CAIF_TTY=m +CONFIG_CAIF_HSI=m CONFIG_SMSC911X=y CONFIG_SMSC_PHY=y +CONFIG_PPP=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_ASYNC=y # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_GPIO=y -CONFIG_KEYBOARD_NOMADIK=y -CONFIG_KEYBOARD_STMPE=y +CONFIG_KEYBOARD_NOMADIK_SKE=y CONFIG_KEYBOARD_TC3589X=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_BU21013=y +CONFIG_TOUCHSCREEN_CYTTSP_CORE=y +CONFIG_TOUCHSCREEN_CYTTSP_SPI=y CONFIG_INPUT_MISC=y +CONFIG_INPUT_AB8500_ACCDET=y CONFIG_INPUT_AB8500_PONKEY=y -# CONFIG_SERIO is not set +CONFIG_INPUT_UINPUT=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_AMBA_PL011_CLOCK_CONTROL=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_NOMADIK=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_NOMADIK=y CONFIG_SPI=y CONFIG_SPI_PL022=y -CONFIG_GPIO_STMPE=y +CONFIG_GPIO_SYSFS=y CONFIG_GPIO_TC3589X=y +CONFIG_GPIO_AB8500=y CONFIG_POWER_SUPPLY=y CONFIG_AB8500_BM=y CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y -CONFIG_MFD_STMPE=y +CONFIG_SENSORS_AB8500=y +CONFIG_SENSORS_DBX500=y +CONFIG_SENSORS_LSM303DLH=y +CONFIG_SENSORS_LSM303DLHC=y +CONFIG_SENSORS_L3G4200D=y +CONFIG_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_UX500_WATCHDOG_DEBUG=y CONFIG_MFD_TC3589X=y CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y +CONFIG_MFD_DB8500_PRCMU=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y CONFIG_REGULATOR_AB8500=y -# CONFIG_HID_SUPPORT is not set +CONFIG_REGULATOR_DB8500_PRCMU=y +CONFIG_REGULATOR_AB8500_DEBUG=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_VIDEO_DEV=y +# CONFIG_VIDEO_CAPTURE_DRIVERS is not set +CONFIG_RADIO_CG2900=y +CONFIG_DRM=y +CONFIG_GPU_MALI=y +CONFIG_FB=y +CONFIG_FB_MCDE=y +CONFIG_MCDE_FB_AVOID_REALLOC=y +CONFIG_MCDE_DISPLAY_SAMSUNG_S6D16D0=y +CONFIG_MCDE_DISPLAY_SONY_ACX424AKP_DSI=y +CONFIG_MCDE_DISPLAY_AV8100=y +# CONFIG_MCDE_DISPLAY_HDMI_FB_AUTO_CREATE is not set +CONFIG_AV8100_HWTRIG_I2SDAT3=y +CONFIG_FB_B2R2=y +CONFIG_B2R2_PLUG_CONF=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_UX500=y +CONFIG_SND_SOC_UX500_AB5500=y +CONFIG_SND_SOC_UX500_AB8500=y +CONFIG_SND_SOC_UX500_CG29XX=y +CONFIG_SND_SOC_UX500_AV8100=y +CONFIG_HIDRAW=y +CONFIG_USB=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_MON=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_UX500=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_LIBUSUAL=y CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_MULTI=m +# CONFIG_USB_G_MULTI_RNDIS is not set +CONFIG_USB_G_HID=m CONFIG_AB8500_USB=y CONFIG_MMC=y -CONFIG_MMC_CLKGATE=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_BLOCK_MINORS=32 +# CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_LM3530=y -CONFIG_LEDS_LP5521=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AB=y CONFIG_RTC_DRV_AB8500=y -CONFIG_RTC_DRV_PL031=y CONFIG_DMADEVICES=y CONFIG_STE_DMA40=y CONFIG_STAGING=y +CONFIG_AB5500_SIM=y +CONFIG_CG2900=y +CONFIG_CG2900_CHIP=y +CONFIG_STLC2690_CHIP=y +CONFIG_CG2900_UART=y +CONFIG_CG2900_AUDIO=y +CONFIG_CG2900_TEST=y +CONFIG_BT_CG2900=y CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y +CONFIG_CW1200=m +CONFIG_CW1200_USE_GPIO_IRQ=y +CONFIG_CW1200_DEBUGFS=y +CONFIG_U8500_MMIO=y +CONFIG_U8500_CM=y +CONFIG_U8500_FLASH=y CONFIG_HSEM_U8500=y +CONFIG_MODEM_U8500=y +CONFIG_U8500_SHRM=y +CONFIG_U8500_SHRM_MODEM_SILENT_RESET=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_QUOTA=y +CONFIG_QFMT_V2=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y -CONFIG_CONFIGFS_FS=m -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y +CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -# CONFIG_SCHED_DEBUG is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_INFO=y -# CONFIG_FTRACE is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_FUNCTION_TRACER=y +CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_USER=y +CONFIG_KEYS=y +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_TWOFISH=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DEV_UX500=y +CONFIG_CRYPTO_DEV_UX500_HASH=y +CONFIG_CRC7=y diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index d5d8d5c7268..a4bf3199819 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -84,6 +84,14 @@ * - kaddr - page address * - size - region size * + * clean_dcache_all() + * + * Cleans the entire d-cache. + * + * flush_dcache_all() + * + * Flushes the entire d-cache. + * * DMA Cache Coherency * =================== * @@ -104,6 +112,9 @@ struct cpu_cache_fns { void (*coherent_user_range)(unsigned long, unsigned long); void (*flush_kern_dcache_area)(void *, size_t); + void (*clean_dcache_all)(void); + void (*flush_dcache_all)(void); + void (*dma_map_area)(const void *, size_t, int); void (*dma_unmap_area)(const void *, size_t, int); @@ -124,6 +135,8 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range #define __cpuc_coherent_user_range cpu_cache.coherent_user_range #define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area +#define __cpuc_clean_dcache_all cpu_cache.clean_dcache_all +#define __cpuc_flush_dcache_all cpu_cache.flush_dcache_all /* * These are private to the dma-mapping API. Do not use directly. @@ -144,6 +157,8 @@ extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); extern void __cpuc_coherent_user_range(unsigned long, unsigned long); extern void __cpuc_flush_dcache_area(void *, size_t); +extern void __cpuc_clean_dcache_all(void); +extern void __cpuc_flush_dcache_all(void); /* * These are private to the dma-mapping API. Do not use directly. diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h index b2deda18154..91063a3976f 100644 --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h @@ -8,7 +8,7 @@ #include <asm/param.h> /* HZ */ -extern void __delay(int loops); +extern void __delay(unsigned long loops); /* * This function intentionally does not exist; if you see references to @@ -40,5 +40,14 @@ extern void __const_udelay(unsigned long); __const_udelay((n) * ((2199023U*HZ)>>11))) : \ __udelay(n)) +extern void (*delay_fn)(unsigned long); + +static inline void set_delay_fn(void (*fn)(unsigned long)) +{ + delay_fn = fn; +} + +extern void read_current_timer_delay_loop(unsigned long loops); + #endif /* defined(_ARM_DELAY_H) */ diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 38050b1c480..cd644aade4c 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -96,8 +96,8 @@ struct elf32_hdr; /* * This is used to ensure we don't load something for the wrong architecture. */ -extern int elf_check_arch(const struct elf32_hdr *); -#define elf_check_arch elf_check_arch +extern int arm_elf_check_arch(const struct elf32_hdr *); +#define elf_check_arch(x) arm_elf_check_arch((const struct elf32_hdr *)(x)) #define vmcore_elf64_check_arch(x) (0) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 9af5563dd3e..d9a9a19cb68 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -63,6 +63,12 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); #define MT_DEVICE_CACHED 2 #define MT_DEVICE_WC 3 /* + * NOTE : U8500 v1.0/ED cut specific hack. + * look at the commit message for more details + */ +#define MT_BACKUP_RAM 4 + +/* * types 4 onwards can be found in asm/mach/map.h and are undefined * for ioremap */ diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index 53426c66352..e76b9eae8e4 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h @@ -33,6 +33,8 @@ struct outer_cache_fns { #ifdef CONFIG_OUTER_CACHE_SYNC void (*sync)(void); #endif + void (*prefetch_enable)(void); + void (*prefetch_disable)(void); void (*set_debug)(unsigned long); void (*resume)(void); }; @@ -81,6 +83,18 @@ static inline void outer_resume(void) outer_cache.resume(); } +static inline void outer_prefetch_enable(void) +{ + if (outer_cache.prefetch_enable) + outer_cache.prefetch_enable(); +} + +static inline void outer_prefetch_disable(void) +{ + if (outer_cache.prefetch_disable) + outer_cache.prefetch_disable(); +} + #else static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index 0f01f4677bd..e0faaeb30ea 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -42,4 +42,12 @@ static inline void twd_local_timer_of_register(void) } #endif +#if defined(CONFIG_HOTPLUG) || defined(CONFIG_CPU_IDLE) +void twd_save(void); +void twd_restore(void); +#else +static inline void twd_save(void) { } +static inline void twd_restore(void) { } +#endif + #endif diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index b57c75e0b01..f1a50f37efd 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -48,10 +48,6 @@ extern void __aeabi_ulcmp(void); extern void fpundefinstr(void); - /* platform dependent support */ -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__const_udelay); - /* networking */ EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_from_user); diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c index d0d1e83150c..6602eae1527 100644 --- a/arch/arm/kernel/elf.c +++ b/arch/arm/kernel/elf.c @@ -5,11 +5,13 @@ #include <linux/elf.h> #include <asm/system_info.h> -int elf_check_arch(const struct elf32_hdr *x) +int arm_elf_check_arch(const struct elf32_hdr *x) { unsigned int eflags; /* Make sure it's an ARM executable */ + if (x->e_ident[EI_CLASS] != ELF_CLASS) + return 0; if (x->e_machine != EM_ARM) return 0; @@ -36,7 +38,7 @@ int elf_check_arch(const struct elf32_hdr *x) } return 1; } -EXPORT_SYMBOL(elf_check_arch); +EXPORT_SYMBOL(arm_elf_check_arch); void elf_set_personality(const struct elf32_hdr *x) { diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ba386bd9410..180dd9f5b19 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -853,6 +853,25 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, return ret; } +static int hw_breakpoint_undef(struct pt_regs *regs, unsigned int instr) +{ + int reg = (instr >> 12) & 15; + + /* Fake sticky power-down cleared */ + regs->uregs[reg] = 0; + regs->ARM_pc += 4; + + return 0; +} + +static struct undef_hook hw_breakpoint_hook = { + .instr_mask = 0xffff0fff, + .instr_val = 0xee110e95, + .cpsr_mask = MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = hw_breakpoint_undef, +}; + /* * One-time initialisation. */ @@ -899,6 +918,10 @@ static void reset_ctrl_regs(void *unused) /* * Ensure sticky power-down is clear (i.e. debug logic is * powered up). + * + * This could raise an undefined instruction exception. If it + * does, it is fixed up with an undef hook which constructs + * a fake value with the sticky power-down bit cleared. */ asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); if ((dbg_power & 0x1) == 0) @@ -986,6 +1009,8 @@ static int __init arch_hw_breakpoint_init(void) */ register_undef_hook(&debug_reg_hook); + register_undef_hook(&hw_breakpoint_hook); + /* * Reset the breakpoint resources. We assume that a halting * debugger will leave the world in a nice state for us. diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index dfcdb9f7c12..4f868fc5174 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -47,6 +47,7 @@ void machine_crash_nonpanic_core(void *unused) printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n", smp_processor_id()); crash_save_cpu(®s, smp_processor_id()); + atomic_notifier_call_chain(&crash_percpu_notifier_list, 0, NULL); flush_cache_all(); atomic_dec(&waiting_for_crash_ipi); @@ -83,6 +84,8 @@ void machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); + atomic_notifier_call_chain(&crash_percpu_notifier_list, 0, NULL); + atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); smp_call_function(machine_crash_nonpanic_core, NULL, false); msecs = 1000; /* Wait at most a second for the other cpus to stop */ @@ -138,3 +141,13 @@ void machine_kexec(struct kimage *image) soft_restart(reboot_code_buffer_phys); } + +void machine_crash_swreset(void) +{ + printk(KERN_INFO "Software reset on panic!\n"); + + flush_cache_all(); + outer_flush_all(); + outer_disable(); + arm_pm_restart(0, NULL); +} diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 2b7b017a20c..5b644d3e831 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -212,8 +212,17 @@ void cpu_idle(void) leds_event(led_idle_start); while (!need_resched()) { #ifdef CONFIG_HOTPLUG_CPU - if (cpu_is_offline(smp_processor_id())) + if (cpu_is_offline(smp_processor_id())) { + + /* NOTE : preempt_count() should be 0 for dying CPU + * as the CPU will use this very thread when + * it is alive + */ + if (preempt_count()) + preempt_enable_no_resched(); + cpu_die(); + } #endif /* diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c index 8085417555d..0697db65efa 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c @@ -58,10 +58,6 @@ void *return_address(unsigned int level) #else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */ -#if defined(CONFIG_ARM_UNWIND) -#warning "TODO: return_address should use unwind tables" -#endif - void *return_address(unsigned int level) { return NULL; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8f464465977..d0029d1ef7e 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -275,8 +275,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) notify_cpu_starting(cpu); - calibrate_delay(); - smp_store_cpu_info(cpu); /* @@ -423,7 +421,7 @@ static void ipi_timer(void) } #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST -static void smp_timer_broadcast(const struct cpumask *mask) +void smp_timer_broadcast(const struct cpumask *mask) { smp_cross_call(mask, IPI_TIMER); } diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index fef42b21cec..33e4a0456c3 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -33,6 +33,9 @@ static void __iomem *twd_base; static struct clk *twd_clk; static unsigned long twd_timer_rate; +static DEFINE_PER_CPU(u32, twd_ctrl); +static DEFINE_PER_CPU(u32, twd_load); + static struct clock_event_device __percpu **twd_evt; static int twd_ppi; @@ -345,3 +348,24 @@ out: WARN(err, "twd_local_timer_of_register failed (%d)\n", err); } #endif + +#if defined(CONFIG_HOTPLUG) || defined(CONFIG_CPU_IDLE) +void twd_save(void) +{ + int this_cpu = smp_processor_id(); + + per_cpu(twd_ctrl, this_cpu) = __raw_readl(twd_base + TWD_TIMER_CONTROL); + per_cpu(twd_load, this_cpu) = __raw_readl(twd_base + TWD_TIMER_LOAD); + +} + +void twd_restore(void) +{ + int this_cpu = smp_processor_id(); + + __raw_writel(per_cpu(twd_ctrl, this_cpu), + twd_base + TWD_TIMER_CONTROL); + __raw_writel(per_cpu(twd_load, this_cpu), + twd_base + TWD_TIMER_LOAD); +} +#endif diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S deleted file mode 100644 index 3c9a05c8d20..00000000000 --- a/arch/arm/lib/delay.S +++ /dev/null @@ -1,69 +0,0 @@ -/* - * linux/arch/arm/lib/delay.S - * - * Copyright (C) 1995, 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/linkage.h> -#include <asm/assembler.h> -#include <asm/param.h> - .text - -.LC0: .word loops_per_jiffy -.LC1: .word (2199023*HZ)>>11 - -/* - * r0 <= 2000 - * lpj <= 0x01ffffff (max. 3355 bogomips) - * HZ <= 1000 - */ - -ENTRY(__udelay) - ldr r2, .LC1 - mul r0, r2, r0 -ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 - mov r1, #-1 - ldr r2, .LC0 - ldr r2, [r2] @ max = 0x01ffffff - add r0, r0, r1, lsr #32-14 - mov r0, r0, lsr #14 @ max = 0x0001ffff - add r2, r2, r1, lsr #32-10 - mov r2, r2, lsr #10 @ max = 0x00007fff - mul r0, r2, r0 @ max = 2^32-1 - add r0, r0, r1, lsr #32-6 - movs r0, r0, lsr #6 - moveq pc, lr - -/* - * loops = r0 * HZ * loops_per_jiffy / 1000000 - * - * Oh, if only we had a cycle counter... - */ - -@ Delay routine -ENTRY(__delay) - subs r0, r0, #1 -#if 0 - movls pc, lr - subs r0, r0, #1 - movls pc, lr - subs r0, r0, #1 - movls pc, lr - subs r0, r0, #1 - movls pc, lr - subs r0, r0, #1 - movls pc, lr - subs r0, r0, #1 - movls pc, lr - subs r0, r0, #1 - movls pc, lr - subs r0, r0, #1 -#endif - bhi __delay - mov pc, lr -ENDPROC(__udelay) -ENDPROC(__const_udelay) -ENDPROC(__delay) diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c new file mode 100644 index 00000000000..b8d636e8ef8 --- /dev/null +++ b/arch/arm/lib/delay.c @@ -0,0 +1,81 @@ +/* + * Originally from linux/arch/arm/lib/delay.S + * + * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/timex.h> + +/* + * Oh, if only we had a cycle counter... + */ +static void delay_loop(unsigned long loops) +{ + asm volatile( + "1: subs %0, %0, #1 \n" + " bhi 1b \n" + : /* No output */ + : "r" (loops) + ); +} + +#ifdef ARCH_HAS_READ_CURRENT_TIMER +/* + * Assumes read_current_timer() is monotonically increasing + * across calls and wraps at most once within MAX_UDELAY_MS. + */ +void read_current_timer_delay_loop(unsigned long loops) +{ + unsigned long bclock, now; + + read_current_timer(&bclock); + do { + read_current_timer(&now); + } while ((now - bclock) < loops); +} +#endif + +void (*delay_fn)(unsigned long) = delay_loop; + +/* + * loops = usecs * HZ * loops_per_jiffy / 1000000 + */ +void __delay(unsigned long loops) +{ + delay_fn(loops); +} +EXPORT_SYMBOL(__delay); + +/* + * 0 <= xloops <= 0x7fffff06 + * loops_per_jiffy <= 0x01ffffff (max. 3355 bogomips) + */ +void __const_udelay(unsigned long xloops) +{ + unsigned long lpj; + unsigned long loops; + + xloops >>= 14; /* max = 0x01ffffff */ + lpj = loops_per_jiffy >> 10; /* max = 0x0001ffff */ + loops = lpj * xloops; /* max = 0x00007fff */ + loops >>= 6; /* max = 2^32-1 */ + + if (likely(loops)) + __delay(loops); +} +EXPORT_SYMBOL(__const_udelay); + +/* + * usecs <= 2000 + * HZ <= 1000 + */ +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * ((2199023UL*HZ)>>11)); +} +EXPORT_SYMBOL(__udelay); diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 4bc27fc908f..165435edeed 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -8,6 +8,7 @@ obj-y := clock.o cpu.o devices.o \ uart-db8500.o clock-debug.o obj-y += pm/ test/ obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o ifeq ($(CONFIG_UX500_SOC_DB5500), y) diff --git a/arch/arm/mach-ux500/board-mop500-bm.c b/arch/arm/mach-ux500/board-mop500-bm.c new file mode 100644 index 00000000000..afdc6ee59a3 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-bm.c @@ -0,0 +1,517 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL), version 2 + * + * U8500 board specific charger and battery initialization parameters. + * + * Author: Johan Palsson <johan.palsson@stericsson.com> for ST-Ericsson. + * Author: Johan Gardsmark <johan.gardsmark@stericsson.com> for ST-Ericsson. + * + */ + +#include <linux/power_supply.h> +#include <linux/mfd/abx500.h> +#include <linux/mfd/abx500/ab8500-bm.h> +#include <linux/mfd/ab8500/pwmleds.h> +#include "board-mop500-bm.h" + +#ifdef CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL +/* + * These are the defined batteries that uses a NTC and ID resistor placed + * inside of the battery pack. + * Note that the res_to_temp table must be strictly sorted by falling resistance + * values to work. + */ +static struct abx500_res_to_temp temp_tbl_A[] = { + {-5, 53407}, + { 0, 48594}, + { 5, 43804}, + {10, 39188}, + {15, 34870}, + {20, 30933}, + {25, 27422}, + {30, 24347}, + {35, 21694}, + {40, 19431}, + {45, 17517}, + {50, 15908}, + {55, 14561}, + {60, 13437}, + {65, 12500}, +}; +static struct abx500_res_to_temp temp_tbl_B[] = { + {-5, 165418}, + { 0, 159024}, + { 5, 151921}, + {10, 144300}, + {15, 136424}, + {20, 128565}, + {25, 120978}, + {30, 113875}, + {35, 107397}, + {40, 101629}, + {45, 96592}, + {50, 92253}, + {55, 88569}, + {60, 85461}, + {65, 82869}, +}; +static struct abx500_v_to_cap cap_tbl_A[] = { + {4171, 100}, + {4114, 95}, + {4009, 83}, + {3947, 74}, + {3907, 67}, + {3863, 59}, + {3830, 56}, + {3813, 53}, + {3791, 46}, + {3771, 33}, + {3754, 25}, + {3735, 20}, + {3717, 17}, + {3681, 13}, + {3664, 8}, + {3651, 6}, + {3635, 5}, + {3560, 3}, + {3408, 1}, + {3247, 0}, +}; +static struct abx500_v_to_cap cap_tbl_B[] = { + {4161, 100}, + {4124, 98}, + {4044, 90}, + {4003, 85}, + {3966, 80}, + {3933, 75}, + {3888, 67}, + {3849, 60}, + {3813, 55}, + {3787, 47}, + {3772, 30}, + {3751, 25}, + {3718, 20}, + {3681, 16}, + {3660, 14}, + {3589, 10}, + {3546, 7}, + {3495, 4}, + {3404, 2}, + {3250, 0}, +}; +#endif +static struct abx500_v_to_cap cap_tbl[] = { + {4186, 100}, + {4163, 99}, + {4114, 95}, + {4068, 90}, + {3990, 80}, + {3926, 70}, + {3898, 65}, + {3866, 60}, + {3833, 55}, + {3812, 50}, + {3787, 40}, + {3768, 30}, + {3747, 25}, + {3730, 20}, + {3705, 15}, + {3699, 14}, + {3684, 12}, + {3672, 9}, + {3657, 7}, + {3638, 6}, + {3556, 4}, + {3424, 2}, + {3317, 1}, + {3094, 0}, +}; + +/* + * Note that the res_to_temp table must be strictly sorted by falling + * resistance values to work. + */ +static struct abx500_res_to_temp temp_tbl[] = { + {-5, 214834}, + { 0, 162943}, + { 5, 124820}, + {10, 96520}, + {15, 75306}, + {20, 59254}, + {25, 47000}, + {30, 37566}, + {35, 30245}, + {40, 24520}, + {45, 20010}, + {50, 16432}, + {55, 13576}, + {60, 11280}, + {65, 9425}, +}; + +#ifdef CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL +/* + * Note that the batres_vs_temp table must be strictly sorted by falling + * temperature values to work. + */ +static struct batres_vs_temp temp_to_batres_tbl[] = { + { 40, 120}, + { 30, 135}, + { 20, 165}, + { 10, 230}, + { 00, 325}, + {-10, 445}, + {-20, 595}, +}; +#else +/* + * Note that the batres_vs_temp table must be strictly sorted by falling + * temperature values to work. + */ +#ifdef CONFIG_AB8500_9100_LI_ION_BATTERY +#define BATRES 180 +#else +#define BATRES 300 +#endif +static struct batres_vs_temp temp_to_batres_tbl[] = { + { 60, BATRES}, + { 30, BATRES}, + { 20, BATRES}, + { 10, BATRES}, + { 00, BATRES}, + {-10, BATRES}, + {-20, BATRES}, +}; +#endif +static const struct abx500_battery_type bat_type[] = { + [BATTERY_UNKNOWN] = { + /* First element always represent the UNKNOWN battery */ + .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, + .resis_high = 0, + .resis_low = 0, + .battery_resistance = 300, +#ifdef CONFIG_AB8500_9100_LI_ION_BATTERY + .charge_full_design = 2600, +#else + .charge_full_design = 612, +#endif + .nominal_voltage = 3700, +#ifdef CONFIG_AB8500_9100_LI_ION_BATTERY + .termination_vol = 4150, +#else + .termination_vol = 4050, +#endif + .termination_curr = 200, +#ifdef CONFIG_AB8500_9100_LI_ION_BATTERY + .recharge_vol = 4130, + .normal_cur_lvl = 520, + .normal_vol_lvl = 4200, +#else + .recharge_vol = 3990, + .normal_cur_lvl = 400, + .normal_vol_lvl = 4100, +#endif + .maint_a_cur_lvl = 400, + .maint_a_vol_lvl = 4050, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 400, + .maint_b_vol_lvl = 4000, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl), + .batres_tbl = temp_to_batres_tbl, + }, + +#ifdef CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL + { + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, + .resis_high = 53407, + .resis_low = 12500, + .battery_resistance = 300, + .charge_full_design = 900, + .nominal_voltage = 3600, + .termination_vol = 4150, + .termination_curr = 80, + .recharge_vol = 4130, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4100, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A), + .r_to_t_tbl = temp_tbl_A, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A), + .v_to_cap_tbl = cap_tbl_A, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl), + .batres_tbl = temp_to_batres_tbl, + + }, + { + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, + .resis_high = 165418, + .resis_low = 82869, + .battery_resistance = 300, + .charge_full_design = 900, + .nominal_voltage = 3600, + .termination_vol = 4150, + .termination_curr = 80, + .recharge_vol = 4130, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4100, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B), + .r_to_t_tbl = temp_tbl_B, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B), + .v_to_cap_tbl = cap_tbl_B, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl), + .batres_tbl = temp_to_batres_tbl, + }, +#else +/* + * These are the batteries that doesn't have an internal NTC resistor to measure + * its temperature. The temperature in this case is measure with a NTC placed + * near the battery but on the PCB. + */ + { + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, + .resis_high = 76000, + .resis_low = 53000, + .battery_resistance = 300, + .charge_full_design = 900, + .nominal_voltage = 3700, + .termination_vol = 4150, + .termination_curr = 100, + .recharge_vol = 4130, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4100, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl), + .batres_tbl = temp_to_batres_tbl, + }, + { + .name = POWER_SUPPLY_TECHNOLOGY_LION, + .resis_high = 30000, + .resis_low = 10000, + .battery_resistance = 300, + .charge_full_design = 950, + .nominal_voltage = 3700, + .termination_vol = 4150, + .termination_curr = 100, + .recharge_vol = 4130, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4100, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl), + .batres_tbl = temp_to_batres_tbl, + }, + { + .name = POWER_SUPPLY_TECHNOLOGY_LION, + .resis_high = 95000, + .resis_low = 76001, + .battery_resistance = 300, + .charge_full_design = 950, + .nominal_voltage = 3700, + .termination_vol = 4150, + .termination_curr = 100, + .recharge_vol = 4130, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4100, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl), + .batres_tbl = temp_to_batres_tbl, + }, +#endif +}; + +static char *ab8500_charger_supplied_to[] = { + "ab8500_chargalg", + "ab8500_fg", + "ab8500_btemp", +}; + +static char *ab8500_btemp_supplied_to[] = { + "ab8500_chargalg", + "ab8500_fg", +}; + +static char *ab8500_fg_supplied_to[] = { + "ab8500_chargalg", + "ab8500_usb", +}; + +static char *ab8500_chargalg_supplied_to[] = { + "ab8500_fg", +}; + +struct abx500_charger_platform_data ab8500_charger_plat_data = { + .supplied_to = ab8500_charger_supplied_to, + .num_supplicants = ARRAY_SIZE(ab8500_charger_supplied_to), + .autopower_cfg = false, +}; + +struct abx500_btemp_platform_data ab8500_btemp_plat_data = { + .supplied_to = ab8500_btemp_supplied_to, + .num_supplicants = ARRAY_SIZE(ab8500_btemp_supplied_to), +}; + +struct abx500_fg_platform_data ab8500_fg_plat_data = { + .supplied_to = ab8500_fg_supplied_to, + .num_supplicants = ARRAY_SIZE(ab8500_fg_supplied_to), +}; + +struct abx500_chargalg_platform_data ab8500_chargalg_plat_data = { + .supplied_to = ab8500_chargalg_supplied_to, + .num_supplicants = ARRAY_SIZE(ab8500_chargalg_supplied_to), +}; + +static struct ab8500_led_pwm leds_pwm_data[] = { + [0] = { + .pwm_id = 1, + .blink_en = 1, + }, + [1] = { + .pwm_id = 2, + .blink_en = 0, + }, + [2] = { + .pwm_id = 3, + .blink_en = 0, + }, +}; + +struct ab8500_pwmled_platform_data ab8500_pwmled_plat_data = { + .num_pwm = 3, + .leds = leds_pwm_data, +}; + +static const struct abx500_bm_capacity_levels cap_levels = { + .critical = 2, + .low = 10, + .normal = 70, + .high = 95, + .full = 100, +}; + +static const struct abx500_fg_parameters fg = { + .recovery_sleep_timer = 10, + .recovery_total_time = 100, + .init_timer = 1, + .init_discard_time = 5, + .init_total_time = 40, + .high_curr_time = 60, + .accu_charging = 30, + .accu_high_curr = 30, + .high_curr_threshold = 50, + .lowbat_threshold = 3100, + .battok_falling_th_sel0 = 2860, + .battok_raising_th_sel1 = 2860, + .user_cap_limit = 15, + .maint_thres = 97, +}; + +static const struct abx500_maxim_parameters maxi_params = { + .ena_maxi = true, + .chg_curr = 910, + .wait_cycles = 10, + .charger_curr_step = 100, +}; + +static const struct abx500_bm_charger_parameters chg = { + .usb_volt_max = 5500, + .usb_curr_max = 1500, + .ac_volt_max = 7500, + .ac_curr_max = 1500, +}; + +struct abx500_bm_data ab8500_bm_data = { + .temp_under = 3, + .temp_low = 8, + .temp_high = 43, + .temp_over = 48, + .main_safety_tmr_h = 4, + .temp_interval_chg = 20, + .temp_interval_nochg = 120, + .usb_safety_tmr_h = 4, + .bkup_bat_v = BUP_VCH_SEL_2P6V, + .bkup_bat_i = BUP_ICH_SEL_150UA, +#ifdef CONFIG_AB8500_9100_LI_ION_BATTERY + .no_maintenance = true, +#else + .no_maintenance = false, +#endif +#ifdef CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL + .adc_therm = ABx500_ADC_THERM_BATCTRL, +#else + .adc_therm = ABx500_ADC_THERM_BATTEMP, +#endif +#ifdef CONFIG_AB8500_9100_LI_ION_BATTERY + .chg_unknown_bat = true, +#else + .chg_unknown_bat = false, +#endif + .enable_overshoot = false, + .fg_res = 100, + .cap_levels = &cap_levels, + .bat_type = bat_type, + .n_btypes = ARRAY_SIZE(bat_type), + .batt_id = 0, + .interval_charging = 5, + .interval_not_charging = 120, + .temp_hysteresis = 3, + .gnd_lift_resistance = 34, + .maxi = &maxi_params, + .chg_params = &chg, + .fg_params = &fg, +}; diff --git a/arch/arm/mach-ux500/board-mop500-bm.h b/arch/arm/mach-ux500/board-mop500-bm.h new file mode 100644 index 00000000000..61d6bc71cc3 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-bm.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL), version 2 + * + * U8500 board specific charger and battery initialization parameters. + * + * Author: Johan Palsson <johan.palsson@stericsson.com> for ST-Ericsson. + * Author: Johan Gardsmark <johan.gardsmark@stericsson.com> for ST-Ericsson. + * + */ + +#ifndef __BOARD_MOP500_BM_H +#define __BOARD_MOP500_BM_H + +#include <linux/mfd/abx500/ab8500-bm.h> + +extern struct abx500_charger_platform_data ab8500_charger_plat_data; +extern struct abx500_btemp_platform_data ab8500_btemp_plat_data; +extern struct abx500_fg_platform_data ab8500_fg_plat_data; +extern struct abx500_chargalg_platform_data ab8500_chargalg_plat_data; +extern struct abx500_bm_data ab8500_bm_data; +extern struct ab8500_pwmled_platform_data ab8500_pwmled_plat_data; + +#endif diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 52426a42578..ffa0d4f9cdc 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -11,8 +11,52 @@ #include <linux/kernel.h> #include <linux/regulator/machine.h> #include <linux/regulator/ab8500.h> +#include <mach/id.h> /* to identify older boards for fixes */ +#include <asm/mach-types.h> #include "board-mop500-regulators.h" +#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE +/* + * GPIO regulator controlled by the ab8500 GPIO16 + */ +static struct regulator_consumer_supply gpio_wlan_vbat_consumers[] = { + /* for cg2900 chip */ + REGULATOR_SUPPLY("vdd", "cg2900-uart.0"), + /* for cw1200 chip */ + REGULATOR_SUPPLY("vdd", "cw1200_wlan"), +}; + +struct regulator_init_data gpio_wlan_vbat_regulator = { + .constraints = { + .name = "WLAN-VBAT", + .min_uV = 3600000, + .max_uV = 3600000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(gpio_wlan_vbat_consumers), + .consumer_supplies = gpio_wlan_vbat_consumers, +}; + +/* + * GPIO regulator controlled by the ab8500 GPIO26 + */ +static struct regulator_consumer_supply gpio_en_3v3_consumers[] = { + /* for LAN chip */ + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +struct regulator_init_data gpio_en_3v3_regulator = { + .constraints = { + .name = "EN-3V3", + .min_uV = 3300000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(gpio_en_3v3_consumers), + .consumer_supplies = gpio_en_3v3_consumers, +}; +#endif + /* * TPS61052 regulator */ @@ -38,21 +82,37 @@ struct regulator_init_data tps61052_regulator = { }; static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { - /* External displays, connector on board 2v5 power supply */ - REGULATOR_SUPPLY("vaux12v5", "mcde.0"), + /* Main display, u8500 R3 uib */ + REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"), + /* Main display, u8500 uib and ST uib */ + REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.0"), + /* Secondary display, ST uib */ + REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.1"), /* SFH7741 proximity sensor */ REGULATOR_SUPPLY("vcc", "gpio-keys.0"), /* BH1780GLS ambient light sensor */ REGULATOR_SUPPLY("vcc", "2-0029"), /* lsm303dlh accelerometer */ - REGULATOR_SUPPLY("vdd", "3-0018"), + REGULATOR_SUPPLY("vdd", "lsm303dlh.0"), /* lsm303dlh magnetometer */ - REGULATOR_SUPPLY("vdd", "3-001e"), + REGULATOR_SUPPLY("vdd", "lsm303dlh.1"), /* Rohm BU21013 Touchscreen devices */ REGULATOR_SUPPLY("avdd", "3-005c"), REGULATOR_SUPPLY("avdd", "3-005d"), /* Synaptics RMI4 Touchscreen device */ REGULATOR_SUPPLY("vdd", "3-004b"), + /* L3G4200D Gyroscope device */ + REGULATOR_SUPPLY("vdd", "l3g4200d"), + /* Proximity and Hal sensor device */ + REGULATOR_SUPPLY("vdd", "sensor1p.0"), + /* Ambient light sensor device */ + REGULATOR_SUPPLY("vdd", "3-0029"), + /* Pressure sensor device */ + REGULATOR_SUPPLY("vdd", "2-005c"), + /* Cypress TrueTouch Touchscreen device */ + REGULATOR_SUPPLY("vcpin", "spi8.0"), + /* Camera device */ + REGULATOR_SUPPLY("vaux12v5", "mmio_camera"), }; static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { @@ -60,6 +120,12 @@ static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { REGULATOR_SUPPLY("vmmc", "sdi4"), /* AB8500 audio codec */ REGULATOR_SUPPLY("vcc-N2158", "ab8500-codec.0"), + /* AB8500 accessory detect 1 */ + REGULATOR_SUPPLY("vcc-N2158", "ab8500-acc-det.0"), + /* AB8500 Tv-out device */ + REGULATOR_SUPPLY("vcc-N2158", "mcde_tv_ab8500.4"), + /* AV8100 HDMI device */ + REGULATOR_SUPPLY("vcc-N2158", "av8100_hdmi.3"), }; static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { @@ -72,26 +138,30 @@ static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"), /* Internal general-purpose ADC */ REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), + /* ADC for charger */ + REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"), + /* AB8500 Tv-out device */ + REGULATOR_SUPPLY("vtvout", "mcde_tv_ab8500.4"), }; static struct regulator_consumer_supply ab8500_vaud_consumers[] = { /* AB8500 audio-codec main supply */ - REGULATOR_SUPPLY("vaud", "ab8500-codec.0"), + REGULATOR_SUPPLY("v-audio", NULL), }; static struct regulator_consumer_supply ab8500_vamic1_consumers[] = { /* AB8500 audio-codec Mic1 supply */ - REGULATOR_SUPPLY("vamic1", "ab8500-codec.0"), + REGULATOR_SUPPLY("v-amic1", NULL), }; static struct regulator_consumer_supply ab8500_vamic2_consumers[] = { /* AB8500 audio-codec Mic2 supply */ - REGULATOR_SUPPLY("vamic2", "ab8500-codec.0"), + REGULATOR_SUPPLY("v-amic2", NULL), }; static struct regulator_consumer_supply ab8500_vdmic_consumers[] = { /* AB8500 audio-codec DMic supply */ - REGULATOR_SUPPLY("vdmic", "ab8500-codec.0"), + REGULATOR_SUPPLY("v-dmic", NULL), }; static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { @@ -102,74 +172,85 @@ static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { }; static struct regulator_consumer_supply ab8500_vana_consumers[] = { - /* External displays, connector on board, 1v8 power supply */ - REGULATOR_SUPPLY("vsmps2", "mcde.0"), + /* DB8500 DSI */ + REGULATOR_SUPPLY("vdddsi1v2", "mcde"), + /* DB8500 CSI */ + REGULATOR_SUPPLY("vddcsi1v2", "mmio_camera"), +}; + +static struct regulator_consumer_supply ab8500_sysclkreq_2_consumers[] = { + /* CG2900 device */ + REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"), +}; + +static struct regulator_consumer_supply ab8500_sysclkreq_4_consumers[] = { + /* CW1200 device */ + REGULATOR_SUPPLY("wlan_1v8", "cw1200_wlan.0"), }; /* ab8500 regulator register initialization */ -struct ab8500_regulator_reg_init -ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { +static struct ab8500_regulator_reg_init ab8500_reg_init[] = { /* * VanaRequestCtrl = HP/LP depending on VxRequest * VextSupply1RequestCtrl = HP/LP depending on VxRequest */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xf0, 0x00), /* * VextSupply2RequestCtrl = HP/LP depending on VxRequest * VextSupply3RequestCtrl = HP/LP depending on VxRequest * Vaux1RequestCtrl = HP/LP depending on VxRequest * Vaux2RequestCtrl = HP/LP depending on VxRequest */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0xff, 0x00), /* * Vaux3RequestCtrl = HP/LP depending on VxRequest * SwHPReq = Control through SWValid disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x07, 0x00), /* * VanaSysClkReq1HPValid = disabled * Vaux1SysClkReq1HPValid = disabled * Vaux2SysClkReq1HPValid = disabled * Vaux3SysClkReq1HPValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00), /* * VextSupply1SysClkReq1HPValid = disabled * VextSupply2SysClkReq1HPValid = disabled * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x40), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x70, 0x40), /* * VanaHwHPReq1Valid = disabled * Vaux1HwHPreq1Valid = disabled * Vaux2HwHPReq1Valid = disabled * Vaux3HwHPReqValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0xe8, 0x00), /* * VextSupply1HwHPReq1Valid = disabled * VextSupply2HwHPReq1Valid = disabled * VextSupply3HwHPReq1Valid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x07, 0x00), /* * VanaHwHPReq2Valid = disabled * Vaux1HwHPReq2Valid = disabled * Vaux2HwHPReq2Valid = disabled * Vaux3HwHPReq2Valid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0xe8, 0x00), /* * VextSupply1HwHPReq2Valid = disabled * VextSupply2HwHPReq2Valid = disabled * VextSupply3HwHPReq2Valid = HWReq2 controlled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x04), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x07, 0x04), /* * VanaSwHPReqValid = disabled * Vaux1SwHPReqValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0xa0, 0x00), /* * Vaux2SwHPReqValid = disabled * Vaux3SwHPReqValid = disabled @@ -177,7 +258,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * VextSupply2SwHPReqValid = disabled * VextSupply3SwHPReqValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x1f, 0x00), /* * SysClkReq2Valid1 = SysClkReq2 controlled * SysClkReq3Valid1 = disabled @@ -187,7 +268,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * SysClkReq7Valid1 = disabled * SysClkReq8Valid1 = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0x2a), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0xfe, 0x2a), /* * SysClkReq2Valid2 = disabled * SysClkReq3Valid2 = disabled @@ -197,7 +278,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * SysClkReq7Valid2 = disabled * SysClkReq8Valid2 = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0x20), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0xfe, 0x20), /* * VTVoutEna = disabled * Vintcore12Ena = disabled @@ -205,66 +286,62 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * Vintcore12LP = inactive (HP) * VTVoutLP = inactive (HP) */ - INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0x10), + INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0xfe, 0x10), /* * VaudioEna = disabled * VdmicEna = disabled * Vamic1Ena = disabled * Vamic2Ena = disabled */ - INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x1e, 0x00), /* * Vamic1_dzout = high-Z when Vamic1 is disabled * Vamic2_dzout = high-Z when Vamic2 is disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00), /* - * VPll = Hw controlled + * VPll = Hw controlled (NOTE! PRCMU bits) * VanaRegu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x02), + INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x0f, 0x02), /* * VrefDDREna = disabled * VrefDDRSleepMode = inactive (no pulldown) */ - INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x03, 0x00), /* - * VextSupply1Regu = HW control - * VextSupply2Regu = HW control - * VextSupply3Regu = HW control + * VextSupply1Regu = force LP + * VextSupply2Regu = force OFF + * VextSupply3Regu = force HP (-> STBB2=LP and TPS=LP) * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 */ - INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0x2a), + INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0xff, 0x13), /* * Vaux1Regu = force HP * Vaux2Regu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x01), - /* - * Vaux3regu = force off - */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x0f, 0x01), /* - * Vsmps1 = 1.15V + * Vaux3Regu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x24), + INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x03, 0x00), /* - * Vaux1Sel = 2.5 V + * Vaux1Sel = 2.8 V */ - INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x08), + INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x0f, 0x0C), /* * Vaux2Sel = 2.9 V */ - INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0d), + INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0f, 0x0d), /* * Vaux3Sel = 2.91 V */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07), + INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07, 0x07), /* * VextSupply12LP = disabled (no LP) */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x01, 0x00), /* * Vaux1Disch = short discharge time * Vaux2Disch = short discharge time @@ -273,23 +350,24 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * VTVoutDisch = short discharge time * VaudioDisch = short discharge time */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0xfc, 0x00), /* * VanaDisch = short discharge time * VdmicPullDownEna = pulldown disabled when Vdmic is disabled * VdmicDisch = short discharge time */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x16, 0x00), }; /* AB8500 regulators */ -struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { +static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { /* supplies to the display/camera */ [AB8500_LDO_AUX1] = { + .supply_regulator = "ab8500-ext-supply3", .constraints = { .name = "V-DISPLAY", - .min_uV = 2500000, - .max_uV = 2900000, + .min_uV = 2800000, + .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, .boot_on = 1, /* display is on at boot */ @@ -306,24 +384,32 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { }, /* supplies to the on-board eMMC */ [AB8500_LDO_AUX2] = { + .supply_regulator = "ab8500-ext-supply3", .constraints = { .name = "V-eMMC1", .min_uV = 1100000, .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), .consumer_supplies = ab8500_vaux2_consumers, }, /* supply for VAUX3, supplies to SDcard slots */ [AB8500_LDO_AUX3] = { + .supply_regulator = "ab8500-ext-supply3", .constraints = { .name = "V-MMC-SD", .min_uV = 1100000, .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), .consumer_supplies = ab8500_vaux3_consumers, @@ -377,18 +463,167 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { [AB8500_LDO_INTCORE] = { .constraints = { .name = "V-INTCORE", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .min_uV = 1250000, + .max_uV = 1350000, + .input_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE | + REGULATOR_CHANGE_DRMS, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), .consumer_supplies = ab8500_vintcore_consumers, }, - /* supply for U8500 CSI/DSI, VANA LDO */ + /* supply for U8500 CSI-DSI, VANA LDO */ [AB8500_LDO_ANA] = { .constraints = { - .name = "V-CSI/DSI", + .name = "V-CSI-DSI", .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), .consumer_supplies = ab8500_vana_consumers, }, + /* sysclkreq 2 pin */ + [AB8500_SYSCLKREQ_2] = { + .constraints = { + .name = "V-SYSCLKREQ-2", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = + ARRAY_SIZE(ab8500_sysclkreq_2_consumers), + .consumer_supplies = ab8500_sysclkreq_2_consumers, + }, + /* sysclkreq 4 pin */ + [AB8500_SYSCLKREQ_4] = { + .constraints = { + .name = "V-SYSCLKREQ-4", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = + ARRAY_SIZE(ab8500_sysclkreq_4_consumers), + .consumer_supplies = ab8500_sysclkreq_4_consumers, + }, }; + +/* supply for VextSupply3 */ +static struct regulator_consumer_supply ab8500_ext_supply3_consumers[] = { + /* SIM supply for 3 V SIM cards */ + REGULATOR_SUPPLY("vinvsim", "sim-detect.0"), +}; + +/* extended configuration for VextSupply2, only used for HREFP_V20 boards */ +static struct ab8500_ext_regulator_cfg ab8500_ext_supply2 = { + .hwreq = true, +}; + +/* + * AB8500 external regulators + */ +static struct regulator_init_data ab8500_ext_regulators[] = { + /* fixed Vbat supplies VSMPS1_EXT_1V8 */ + [AB8500_EXT_SUPPLY1] = { + .constraints = { + .name = "ab8500-ext-supply1", + .min_uV = 1800000, + .max_uV = 1800000, + .initial_mode = REGULATOR_MODE_IDLE, + .boot_on = 1, + .always_on = 1, + }, + }, + /* fixed Vbat supplies VSMPS2_EXT_1V36 and VSMPS5_EXT_1V15 */ + [AB8500_EXT_SUPPLY2] = { + .constraints = { + .name = "ab8500-ext-supply2", + .min_uV = 1360000, + .max_uV = 1360000, + }, + }, + /* fixed Vbat supplies VSMPS3_EXT_3V4 and VSMPS4_EXT_3V4 */ + [AB8500_EXT_SUPPLY3] = { + .constraints = { + .name = "ab8500-ext-supply3", + .min_uV = 3400000, + .max_uV = 3400000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = + ARRAY_SIZE(ab8500_ext_supply3_consumers), + .consumer_supplies = ab8500_ext_supply3_consumers, + }, +}; + +struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { + .reg_init = ab8500_reg_init, + .num_reg_init = ARRAY_SIZE(ab8500_reg_init), + .regulator = ab8500_regulators, + .num_regulator = ARRAY_SIZE(ab8500_regulators), + .ext_regulator = ab8500_ext_regulators, + .num_ext_regulator = ARRAY_SIZE(ab8500_ext_regulators), +}; + +static void ab8500_modify_reg_init(int id, u8 mask, u8 value) +{ + int i; + + for (i = ARRAY_SIZE(ab8500_reg_init) - 1; i >= 0; i--) { + if (ab8500_reg_init[i].id == id) { + u8 initval = ab8500_reg_init[i].value; + initval = (initval & ~mask) | (value & mask); + ab8500_reg_init[i].value = initval; + + BUG_ON(mask & ~ab8500_reg_init[i].mask); + return; + } + } + + BUG_ON(1); +} + +void mop500_regulator_init(void) +{ + struct regulator_init_data *regulator; + + /* + * Temporarily turn on Vaux2 on 8520 machine + */ + if (machine_is_u8520()) { + /* Vaux2 initialized to be on */ + ab8500_modify_reg_init(AB8500_VAUX12REGU, 0x0f, 0x05); + + /* Vaux2 always on */ + regulator = &ab8500_ext_regulators[AB8500_LDO_AUX2]; + regulator->constraints.always_on = 1; + } + + /* + * Handle AB8500_EXT_SUPPLY2 on HREFP_V20_V50 boards (do it for + * all HREFP_V20 boards) + */ + if (cpu_is_u8500v20()) { + /* VextSupply2RequestCtrl = HP/OFF depending on VxRequest */ + ab8500_modify_reg_init(AB8500_REGUREQUESTCTRL3, 0x01, 0x01); + + /* VextSupply2SysClkReq1HPValid = SysClkReq1 controlled */ + ab8500_modify_reg_init(AB8500_REGUSYSCLKREQ1HPVALID2, + 0x20, 0x20); + + /* VextSupply2 = force HP at initialization */ + ab8500_modify_reg_init(AB8500_EXTSUPPLYREGU, 0x0c, 0x04); + + /* enable VextSupply2 during platform active */ + regulator = &ab8500_ext_regulators[AB8500_EXT_SUPPLY2]; + regulator->constraints.always_on = 1; + + /* disable VextSupply2 in suspend */ + regulator = &ab8500_ext_regulators[AB8500_EXT_SUPPLY2]; + regulator->constraints.state_mem.disabled = 1; + regulator->constraints.state_standby.disabled = 1; + + /* enable VextSupply2 HW control (used in suspend) */ + regulator->driver_data = (void *)&ab8500_ext_supply2; + } +} diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 94992158d96..b5fc81a3649 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h @@ -14,9 +14,11 @@ #include <linux/regulator/machine.h> #include <linux/regulator/ab8500.h> -extern struct ab8500_regulator_reg_init -ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; -extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; +extern struct ab8500_regulator_platform_data ab8500_regulator_plat_data; extern struct regulator_init_data tps61052_regulator; +extern struct regulator_init_data gpio_wlan_vbat_regulator; +extern struct regulator_init_data gpio_en_3v3_regulator; + +void mop500_regulator_init(void); #endif diff --git a/arch/arm/mach-ux500/board-u5500-bm.c b/arch/arm/mach-ux500/board-u5500-bm.c new file mode 100644 index 00000000000..333f2cb8563 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-bm.c @@ -0,0 +1,497 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL), version 2 + * + * U5500 board specific charger and battery initialization parameters. + * + * License Terms: GNU General Public License v2 + * Authors: + * Johan Palsson <johan.palsson@stericsson.com> + * Karl Komierowski <karl.komierowski@stericsson.com> + */ + +#include <linux/power_supply.h> +#include <linux/mfd/abx500.h> +#include <linux/mfd/abx500/ab5500-bm.h> +#include "board-u5500-bm.h" + +#ifdef CONFIG_AB5500_BATTERY_THERM_ON_BATCTRL +/* + * These are the defined batteries that uses a NTC and ID resistor placed + * inside of the battery pack. + * Note that the abx500_res_to_temp table must be strictly sorted by falling + * resistance values to work. + */ +static struct abx500_res_to_temp temp_tbl_type1[] = { + {-20, 67400}, + { 0, 49200}, + { 5, 44200}, + { 10, 39400}, + { 15, 35000}, + { 20, 31000}, + { 25, 27400}, + { 30, 24300}, + { 35, 21700}, + { 40, 19400}, + { 45, 17500}, + { 50, 15900}, + { 55, 14600}, + { 60, 13500}, + { 65, 12500}, + { 70, 11800}, + {100, 9200}, +}; + +static struct abx500_res_to_temp temp_tbl_type2[] = { + {-20, 180700}, + { 0, 160000}, + { 5, 152700}, + { 10, 144900}, + { 15, 136800}, + { 20, 128700}, + { 25, 121000}, + { 30, 113800}, + { 35, 107300}, + { 40, 101500}, + { 45, 96500}, + { 50, 92200}, + { 55, 88600}, + { 60, 85600}, + { 65, 83000}, + { 70, 80900}, + {100, 73900}, +}; + +static struct abx500_res_to_temp temp_tbl_A[] = { + {-5, 53407}, + { 0, 48594}, + { 5, 43804}, + {10, 39188}, + {15, 34870}, + {20, 30933}, + {25, 27422}, + {30, 24347}, + {35, 21694}, + {40, 19431}, + {45, 17517}, + {50, 15908}, + {55, 14561}, + {60, 13437}, + {65, 12500}, +}; + +static struct abx500_res_to_temp temp_tbl_B[] = { + {-5, 165418}, + { 0, 159024}, + { 5, 151921}, + {10, 144300}, + {15, 136424}, + {20, 128565}, + {25, 120978}, + {30, 113875}, + {35, 107397}, + {40, 101629}, + {45, 96592}, + {50, 92253}, + {55, 88569}, + {60, 85461}, + {65, 82869}, +}; + +static struct abx500_v_to_cap cap_tbl_type1[] = { + {4171, 100}, + {4114, 95}, + {4009, 83}, + {3947, 74}, + {3907, 67}, + {3863, 59}, + {3830, 56}, + {3813, 53}, + {3791, 46}, + {3771, 33}, + {3754, 25}, + {3735, 20}, + {3717, 17}, + {3681, 13}, + {3664, 8}, + {3651, 6}, + {3635, 5}, + {3560, 3}, + {3408, 1}, + {3247, 0}, +}; + +static struct abx500_v_to_cap cap_tbl_A[] = { + {4171, 100}, + {4114, 95}, + {4009, 83}, + {3947, 74}, + {3907, 67}, + {3863, 59}, + {3830, 56}, + {3813, 53}, + {3791, 46}, + {3771, 33}, + {3754, 25}, + {3735, 20}, + {3717, 17}, + {3681, 13}, + {3664, 8}, + {3651, 6}, + {3635, 5}, + {3560, 3}, + {3408, 1}, + {3247, 0}, +}; +static struct abx500_v_to_cap cap_tbl_B[] = { + {4161, 100}, + {4124, 98}, + {4044, 90}, + {4003, 85}, + {3966, 80}, + {3933, 75}, + {3888, 67}, + {3849, 60}, + {3813, 55}, + {3787, 47}, + {3772, 30}, + {3751, 25}, + {3718, 20}, + {3681, 16}, + {3660, 14}, + {3589, 10}, + {3546, 7}, + {3495, 4}, + {3404, 2}, + {3250, 0}, +}; +#endif +static struct abx500_v_to_cap cap_tbl[] = { + {4186, 100}, + {4163, 99}, + {4114, 95}, + {4068, 90}, + {3990, 80}, + {3926, 70}, + {3898, 65}, + {3866, 60}, + {3833, 55}, + {3812, 50}, + {3787, 40}, + {3768, 30}, + {3747, 25}, + {3730, 20}, + {3705, 15}, + {3699, 14}, + {3684, 12}, + {3672, 9}, + {3657, 7}, + {3638, 6}, + {3556, 4}, + {3424, 2}, + {3317, 1}, + {3094, 0}, +}; + +/* + * Note that the abx500_res_to_temp table must be strictly sorted by falling + * resistance values to work. + */ +static struct abx500_res_to_temp temp_tbl[] = { + {-5, 214834}, + { 0, 162943}, + { 5, 124820}, + {10, 96520}, + {15, 75306}, + {20, 59254}, + {25, 47000}, + {30, 37566}, + {35, 30245}, + {40, 24520}, + {45, 20010}, + {50, 16432}, + {55, 13576}, + {60, 11280}, + {65, 9425}, +}; + +static const struct abx500_battery_type bat_type[] = { + [BATTERY_UNKNOWN] = { + /* First element always represent the UNKNOWN battery */ + .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, + .resis_high = 0, + .resis_low = 0, + .battery_resistance = 300, + .charge_full_design = 612, + .nominal_voltage = 3700, + .termination_vol = 4050, + .termination_curr = 200, + .recharge_vol = 3990, + .normal_cur_lvl = 400, + .normal_vol_lvl = 4100, + .maint_a_cur_lvl = 400, + .maint_a_vol_lvl = 4050, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 400, + .maint_b_vol_lvl = 4025, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + }, + +#ifdef CONFIG_AB5500_BATTERY_THERM_ON_BATCTRL + { + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, + .resis_high = 70000, + .resis_low = 8200, + .battery_resistance = 300, + .charge_full_design = 1500, + .nominal_voltage = 3600, + .termination_vol = 4150, + .termination_curr = 80, + .recharge_vol = 4025, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4025, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_type1), + .r_to_t_tbl = temp_tbl_type1, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_type1), + .v_to_cap_tbl = cap_tbl_type1, + + }, + { + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, + .resis_high = 165418, + .resis_low = 82869, + .battery_resistance = 300, + .charge_full_design = 900, + .nominal_voltage = 3600, + .termination_vol = 4150, + .termination_curr = 80, + .recharge_vol = 4025, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4025, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B), + .r_to_t_tbl = temp_tbl_B, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B), + .v_to_cap_tbl = cap_tbl_B, + }, +#else +/* + * These are the batteries that doesn't have an internal NTC resistor to measure + * its temperature. The temperature in this case is measure with a NTC placed + * near the battery but on the PCB. + */ + { + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, + .resis_high = 76000, + .resis_low = 53000, + .battery_resistance = 300, + .charge_full_design = 900, + .nominal_voltage = 3700, + .termination_vol = 4150, + .termination_curr = 100, + .recharge_vol = 4025, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4025, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + }, + { + .name = POWER_SUPPLY_TECHNOLOGY_LION, + .resis_high = 30000, + .resis_low = 10000, + .battery_resistance = 300, + .charge_full_design = 950, + .nominal_voltage = 3700, + .termination_vol = 4150, + .termination_curr = 100, + .recharge_vol = 4025, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4025, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + }, + { + .name = POWER_SUPPLY_TECHNOLOGY_LION, + .resis_high = 95000, + .resis_low = 76001, + .battery_resistance = 300, + .charge_full_design = 950, + .nominal_voltage = 3700, + .termination_vol = 4150, + .termination_curr = 100, + .recharge_vol = 4025, + .normal_cur_lvl = 700, + .normal_vol_lvl = 4200, + .maint_a_cur_lvl = 600, + .maint_a_vol_lvl = 4150, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 600, + .maint_b_vol_lvl = 4025, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + }, +#endif +}; + +static char *ab5500_charger_supplied_to[] = { + "abx500_chargalg", + "ab5500_fg", + "ab5500_btemp", +}; + +static char *ab5500_btemp_supplied_to[] = { + "abx500_chargalg", + "ab5500_fg", +}; + +static char *ab5500_fg_supplied_to[] = { + "abx500_chargalg", +}; + +static char *abx500_chargalg_supplied_to[] = { + "ab5500_fg", +}; + +struct abx500_charger_platform_data ab5500_charger_plat_data = { + .supplied_to = ab5500_charger_supplied_to, + .num_supplicants = ARRAY_SIZE(ab5500_charger_supplied_to), +}; + +struct abx500_btemp_platform_data ab5500_btemp_plat_data = { + .supplied_to = ab5500_btemp_supplied_to, + .num_supplicants = ARRAY_SIZE(ab5500_btemp_supplied_to), +}; + +struct abx500_fg_platform_data ab5500_fg_plat_data = { + .supplied_to = ab5500_fg_supplied_to, + .num_supplicants = ARRAY_SIZE(ab5500_fg_supplied_to), +}; + +struct abx500_chargalg_platform_data abx500_chargalg_plat_data = { + .supplied_to = abx500_chargalg_supplied_to, + .num_supplicants = ARRAY_SIZE(abx500_chargalg_supplied_to), +}; + +static const struct abx500_bm_capacity_levels cap_levels = { + .critical = 2, + .low = 10, + .normal = 70, + .high = 95, + .full = 100, +}; + +static const struct abx500_fg_parameters fg = { + .recovery_sleep_timer = 10, + .recovery_total_time = 100, + .init_timer = 1, + .init_discard_time = 5, + .init_total_time = 40, + .high_curr_time = 60, + .accu_charging = 30, + .accu_high_curr = 30, + .high_curr_threshold = 50, + .lowbat_threshold = 3560, + .overbat_threshold = 4400, +}; + +static const struct abx500_maxim_parameters maxi_params = { + .ena_maxi = true, + .chg_curr = 910, + .wait_cycles = 10, + .charger_curr_step = 100, +}; + +static const struct abx500_bm_charger_parameters chg = { + .usb_volt_max = 5500, + .usb_curr_max = 1500, + .ac_volt_max = 7500, + .ac_curr_max = 1500, +}; + +struct abx500_bm_data ab5500_bm_data = { + .temp_under = 3, + .temp_low = 8, + /* TODO: Need to verify the temp values */ + .temp_high = 155, + .temp_over = 160, + .main_safety_tmr_h = 4, + .usb_safety_tmr_h = 4, + .bkup_bat_v = 0x00, + .bkup_bat_i = 0x00, + .no_maintenance = true, +#ifdef CONFIG_AB5500_BATTERY_THERM_ON_BATCTRL + .adc_therm = ABx500_ADC_THERM_BATCTRL, +#else + .adc_therm = ABx500_ADC_THERM_BATTEMP, +#endif + .chg_unknown_bat = false, + .enable_overshoot = false, + .auto_trig = true, + .fg_res = 200, + .cap_levels = &cap_levels, + .bat_type = bat_type, + .n_btypes = ARRAY_SIZE(bat_type), + .batt_id = 0, + .interval_charging = 5, + .interval_not_charging = 120, + .temp_hysteresis = 3, + .maxi = &maxi_params, + .chg_params = &chg, + .fg_params = &fg, +}; + +/* ab5500 energy management platform data */ +struct abx500_bm_plat_data abx500_bm_pt_data = { + .battery = &ab5500_bm_data, + .charger = &ab5500_charger_plat_data, + .btemp = &ab5500_btemp_plat_data, + .fg = &ab5500_fg_plat_data, + .chargalg = &abx500_chargalg_plat_data, +}; diff --git a/arch/arm/mach-ux500/board-u5500-bm.h b/arch/arm/mach-ux500/board-u5500-bm.h new file mode 100644 index 00000000000..a6346905911 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-bm.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL), version 2 + * + * U5500 board specific charger and battery initialization parameters. + * + * License Terms: GNU General Public License v2 + * Authors: + * Johan Palsson <johan.palsson@stericsson.com> + * Karl Komierowski <karl.komierowski@stericsson.com> + */ + +#ifndef __BOARD_U5500_BM_H +#define __BOARD_U5500_BM_H + +#include <linux/mfd/abx500/ab5500-bm.h> + +extern struct abx500_charger_platform_data ab5500_charger_plat_data; +extern struct abx500_btemp_platform_data ab5500_btemp_plat_data; +extern struct abx500_fg_platform_data ab5500_fg_plat_data; +extern struct abx500_chargalg_platform_data abx500_chargalg_plat_data; +extern struct abx500_bm_data ab5500_bm_data; +extern struct abx500_bm_plat_data abx500_bm_pt_data; + +#endif diff --git a/arch/arm/mach-ux500/board-u5500-regulators.c b/arch/arm/mach-ux500/board-u5500-regulators.c new file mode 100644 index 00000000000..9e343259e53 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-regulators.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/ab5500.h> + +#include "regulator-u5500.h" +#include "board-u5500.h" + +/* + * AB5500 + */ + +static struct regulator_consumer_supply ab5500_ldo_g_consumers[] = { + REGULATOR_SUPPLY("vmmc", "sdi1"), +}; + +static struct regulator_consumer_supply ab5500_ldo_h_consumers[] = { + REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"), + REGULATOR_SUPPLY("vdd", "1-004b"), /* Synaptics */ + REGULATOR_SUPPLY("vin", "2-0036"), /* LM3530 */ + REGULATOR_SUPPLY("vcpin", "spi1.0"), + REGULATOR_SUPPLY("v-ana", "mmio_camera"), + REGULATOR_SUPPLY("vdd", "lsm303dlh.0"), + REGULATOR_SUPPLY("vdd", "lsm303dlh.1"), +}; + +static struct regulator_consumer_supply ab5500_ldo_k_consumers[] = { + REGULATOR_SUPPLY("v-mmio-camera", "mmio_camera"), +}; + +static struct regulator_consumer_supply ab5500_ldo_h_consumers_pre_r3a[] = { + REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"), + REGULATOR_SUPPLY("vdd", "1-004b"), /* Synaptics */ + REGULATOR_SUPPLY("vin", "2-0036"), /* LM3530 */ + REGULATOR_SUPPLY("vcpin", "spi1.0"), + REGULATOR_SUPPLY("v-ana", "mmio_camera"), +}; + +static struct regulator_consumer_supply ab5500_ldo_k_consumers_pre_r3a[] = { + REGULATOR_SUPPLY("vdd", "lsm303dlh.0"), + REGULATOR_SUPPLY("vdd", "lsm303dlh.1"), + REGULATOR_SUPPLY("v-mmio-camera", "mmio_camera"), +}; + +static struct regulator_consumer_supply ab5500_ldo_l_consumers[] = { + REGULATOR_SUPPLY("vmmc", "sdi0"), + REGULATOR_SUPPLY("vmmc", "sdi2"), +}; + +static struct regulator_consumer_supply ab5500_ldo_vdigmic_consumers[] = { + REGULATOR_SUPPLY("vdigmic", "ab5500-codec.0"), +}; + +static struct regulator_consumer_supply ab5500_ldo_sim_consumers[] = { + REGULATOR_SUPPLY("debug", "reg-virt-consumer.5"), +}; + +static struct regulator_consumer_supply ab5500_bias2_consumers[] = { + REGULATOR_SUPPLY("v-amic", NULL), +}; + +static struct regulator_init_data +ab5500_regulator_init_data[AB5500_NUM_REGULATORS] = { + /* SD Card */ + [AB5500_LDO_G] = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2910000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .consumer_supplies = ab5500_ldo_g_consumers, + .num_consumer_supplies = ARRAY_SIZE(ab5500_ldo_g_consumers), + }, + /* Display */ + [AB5500_LDO_H] = { + .constraints = { + .min_uV = 2790000, + .max_uV = 2790000, + .apply_uV = 1, + .boot_on = 1, /* display on during boot */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = ab5500_ldo_h_consumers, + .num_consumer_supplies = ARRAY_SIZE(ab5500_ldo_h_consumers), + }, + /* Camera */ + [AB5500_LDO_K] = { + .constraints = { + .min_uV = 2790000, + .max_uV = 2790000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = ab5500_ldo_k_consumers, + .num_consumer_supplies = ARRAY_SIZE(ab5500_ldo_k_consumers), + }, + /* External eMMC */ + [AB5500_LDO_L] = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2910000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .consumer_supplies = ab5500_ldo_l_consumers, + .num_consumer_supplies = ARRAY_SIZE(ab5500_ldo_l_consumers), + }, + [AB5500_LDO_VDIGMIC] = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = ab5500_ldo_vdigmic_consumers, + .num_consumer_supplies = + ARRAY_SIZE(ab5500_ldo_vdigmic_consumers), + }, + [AB5500_LDO_SIM] = { + .constraints = { + .min_uV = 1875000, + .max_uV = 2900000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = ab5500_ldo_sim_consumers, + .num_consumer_supplies = ARRAY_SIZE(ab5500_ldo_sim_consumers), + }, + [AB5500_BIAS2] = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = ab5500_bias2_consumers, + .num_consumer_supplies = ARRAY_SIZE(ab5500_bias2_consumers), + }, +}; + +static struct ab5500_regulator_data +ab5500_regulator_data[AB5500_NUM_REGULATORS] = { + [AB5500_LDO_H] = { + /* + * The sub camera on the dev boards needs both supplies to be + * on to avoid high leakage. + */ + .off_is_lowpower = true, + }, +}; + +struct ab5500_regulator_platform_data u5500_ab5500_regulator_data = { + .regulator = ab5500_regulator_init_data, + .data = ab5500_regulator_data, + .num_regulator = ARRAY_SIZE(ab5500_regulator_init_data), +}; + + +static void __init u5500_regulators_init_debug(void) +{ + const char data[] = "debug"; + int i; + + for (i = 0; i < 6; i++) + platform_device_register_data(NULL, "reg-virt-consumer", i, + data, sizeof(data)); +} + +static struct regulator_consumer_supply u5500_vio_consumers[] = { + REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"), +}; + +static struct regulator_init_data u5500_vio_init_data = { + .constraints.always_on = 1, + .consumer_supplies = u5500_vio_consumers, + .num_consumer_supplies = ARRAY_SIZE(u5500_vio_consumers), +}; + +static struct fixed_voltage_config u5500_vio_pdata __initdata = { + .supply_name = "vio_1v8", + .microvolts = 1800000, + .init_data = &u5500_vio_init_data, + .gpio = -EINVAL, +}; + +void __init u5500_regulators_init(void) +{ + if (u5500_board_is_pre_r3a()) { + struct regulator_init_data *rid = ab5500_regulator_init_data; + + rid[AB5500_LDO_K].consumer_supplies + = ab5500_ldo_k_consumers_pre_r3a; + rid[AB5500_LDO_K].num_consumer_supplies + = ARRAY_SIZE(ab5500_ldo_k_consumers_pre_r3a); + + rid[AB5500_LDO_H].consumer_supplies + = ab5500_ldo_h_consumers_pre_r3a; + rid[AB5500_LDO_H].num_consumer_supplies + = ARRAY_SIZE(ab5500_ldo_h_consumers_pre_r3a); + } + + u5500_regulators_init_debug(); + + platform_device_register_data(NULL, "reg-fixed-voltage", -1, + &u5500_vio_pdata, + sizeof(u5500_vio_pdata)); + + regulator_has_full_constraints(); +} diff --git a/arch/arm/mach-ux500/clock-db5500.c b/arch/arm/mach-ux500/clock-db5500.c new file mode 100644 index 00000000000..aa61b1129e6 --- /dev/null +++ b/arch/arm/mach-ux500/clock-db5500.c @@ -0,0 +1,745 @@ +/* + * Copyright (C) 2009 ST-Ericsson SA + * Copyright (C) 2009 STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/init.h> +#include <linux/list.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/errno.h> +#include <linux/mutex.h> +#include <linux/debugfs.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <linux/workqueue.h> +#include <linux/gpio/nomadik.h> +#include <linux/regulator/consumer.h> +#include <linux/mfd/abx500.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include <plat/pincfg.h> + +#include <mach/hardware.h> + +#include "clock.h" +#include "pins-db5500.h" + +static DEFINE_MUTEX(sysclk_mutex); +static DEFINE_MUTEX(pll_mutex); + +/* SysClk operations. */ +static int sysclk_enable(struct clk *clk) +{ + return prcmu_request_clock(PRCMU_SYSCLK, true); +} + +static void sysclk_disable(struct clk *clk) +{ + + prcmu_request_clock(PRCMU_SYSCLK, false); + return; +} + +static struct clkops sysclk_ops = { + .enable = sysclk_enable, + .disable = sysclk_disable, +}; + +static int rtc_clk_enable(struct clk *clk) +{ + return ab5500_clock_rtc_enable(clk->cg_sel, true); +} + +static void rtc_clk_disable(struct clk *clk) +{ + int ret = ab5500_clock_rtc_enable(clk->cg_sel, false); + + if (ret) + pr_err("clock: %s failed to disable: %d\n", clk->name, ret); +} + +static struct clkops rtc_clk_ops = { + .enable = rtc_clk_enable, + .disable = rtc_clk_disable, +}; + +static pin_cfg_t clkout0_pins[] = { + GPIO161_CLKOUT_0 | PIN_OUTPUT_LOW, +}; + +static pin_cfg_t clkout1_pins[] = { + GPIO162_CLKOUT_1 | PIN_OUTPUT_LOW, +}; + +static int clkout0_enable(struct clk *clk) +{ + return nmk_config_pins(clkout0_pins, ARRAY_SIZE(clkout0_pins)); +} + +static void clkout0_disable(struct clk *clk) +{ + int r; + + r = nmk_config_pins_sleep(clkout0_pins, ARRAY_SIZE(clkout0_pins)); + if (!r) + return; + + pr_err("clock: failed to disable %s.\n", clk->name); +} + +static int clkout1_enable(struct clk *clk) +{ + return nmk_config_pins(clkout1_pins, ARRAY_SIZE(clkout0_pins)); +} + +static void clkout1_disable(struct clk *clk) +{ + int r; + + r = nmk_config_pins_sleep(clkout1_pins, ARRAY_SIZE(clkout1_pins)); + if (!r) + return; + + pr_err("clock: failed to disable %s.\n", clk->name); +} + +static struct clkops clkout0_ops = { + .enable = clkout0_enable, + .disable = clkout0_disable, +}; + +static struct clkops clkout1_ops = { + .enable = clkout1_enable, + .disable = clkout1_disable, +}; + +#define PRCM_CLKOCR2 0x58C +#define PRCM_CLKOCR2_REFCLK (1 << 0) +#define PRCM_CLKOCR2_STATIC0 (1 << 2) + +static int clkout2_enable(struct clk *clk) +{ + prcmu_write(PRCM_CLKOCR2, PRCM_CLKOCR2_REFCLK); + return 0; +} + +static void clkout2_disable(struct clk *clk) +{ + prcmu_write(PRCM_CLKOCR2, PRCM_CLKOCR2_STATIC0); +} + +static struct clkops clkout2_ops = { + .enable = clkout2_enable, + .disable = clkout2_disable, +}; + +#define DEF_PER1_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U5500_CLKRST1_BASE, _cg_bit, &per1clk) +#define DEF_PER2_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U5500_CLKRST2_BASE, _cg_bit, &per2clk) +#define DEF_PER3_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U5500_CLKRST3_BASE, _cg_bit, &per3clk) +#define DEF_PER5_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U5500_CLKRST5_BASE, _cg_bit, &per5clk) +#define DEF_PER6_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U5500_CLKRST6_BASE, _cg_bit, &per6clk) + +#define DEF_PER1_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U5500_CLKRST1_BASE, _cg_bit, _parent, &per1clk) +#define DEF_PER2_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U5500_CLKRST2_BASE, _cg_bit, _parent, &per2clk) +#define DEF_PER3_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U5500_CLKRST3_BASE, _cg_bit, _parent, &per3clk) +#define DEF_PER5_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U5500_CLKRST5_BASE, _cg_bit, _parent, &per5clk) +#define DEF_PER6_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U5500_CLKRST6_BASE, _cg_bit, _parent, &per6clk) + +/* Clock sources. */ + +static struct clk soc0_pll = { + .name = "soc0_pll", + .ops = &prcmu_clk_ops, + .mutex = &pll_mutex, + .cg_sel = PRCMU_PLLSOC0, +}; + +static struct clk soc1_pll = { + .name = "soc1_pll", + .ops = &prcmu_clk_ops, + .mutex = &pll_mutex, + .cg_sel = PRCMU_PLLSOC1, +}; + +static struct clk ddr_pll = { + .name = "ddr_pll", + .ops = &prcmu_clk_ops, + .mutex = &pll_mutex, + .cg_sel = PRCMU_PLLDDR, +}; + +static struct clk sysclk = { + .name = "sysclk", + .ops = &sysclk_ops, + .rate = 26000000, + .mutex = &sysclk_mutex, +}; + +static struct clk rtc32k = { + .name = "rtc32k", + .rate = 32768, +}; + +static struct clk kbd32k = { + .name = "kbd32k", + .rate = 32768, +}; + +static struct clk clk_dummy = { + .name = "dummy", +}; + +static struct clk rtc_clk1 = { + .name = "rtc_clk1", + .ops = &rtc_clk_ops, + .cg_sel = 1, + .mutex = &sysclk_mutex, +}; + +static struct clk clkout0 = { + .name = "clkout0", + .ops = &clkout0_ops, + .parent = &sysclk, + .mutex = &sysclk_mutex, +}; + +static struct clk clkout1 = { + .name = "clkout1", + .ops = &clkout1_ops, + .parent = &sysclk, + .mutex = &sysclk_mutex, +}; + +static struct clk clkout2 = { + .name = "clkout2", + .ops = &clkout2_ops, + .parent = &sysclk, + .mutex = &sysclk_mutex, +}; + +static DEFINE_MUTEX(parented_prcmu_mutex); + +#define DEF_PRCMU_CLK_PARENT(_name, _cg_sel, _rate, _parent) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcmu_clk_ops, \ + .cg_sel = _cg_sel, \ + .rate = _rate, \ + .parent = _parent, \ + .mutex = &parented_prcmu_mutex, \ + } + +static DEFINE_MUTEX(prcmu_client_mutex); + +#define DEF_PRCMU_CLIENT_CLK(_name, _cg_sel, _rate) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcmu_clk_ops, \ + .cg_sel = _cg_sel, \ + .rate = _rate, \ + .mutex = &prcmu_client_mutex, \ + } + +static DEF_PRCMU_CLK(dmaclk, PRCMU_DMACLK, 200000000); +static DEF_PRCMU_CLK(b2r2clk, PRCMU_B2R2CLK, 200000000); +static DEF_PRCMU_CLK(sgaclk, PRCMU_SGACLK, 199900000); +static DEF_PRCMU_CLK(uartclk, PRCMU_UARTCLK, 36360000); +static DEF_PRCMU_CLK(msp02clk, PRCMU_MSP02CLK, 13000000); +static DEF_PRCMU_CLIENT_CLK(msp1clk, PRCMU_MSP1CLK, 26000000); +static DEF_PRCMU_CLIENT_CLK(cdclk, PRCMU_CDCLK, 26000000); +static DEF_PRCMU_CLK(i2cclk, PRCMU_I2CCLK, 24000000); +static DEF_PRCMU_CLK_PARENT(irdaclk, PRCMU_IRDACLK, 48000000, &soc1_pll); +static DEF_PRCMU_CLK_PARENT(irrcclk, PRCMU_IRRCCLK, 48000000, &soc1_pll); +static DEF_PRCMU_CLK(rngclk, PRCMU_RNGCLK, 26000000); +static DEF_PRCMU_CLK(pwmclk, PRCMU_PWMCLK, 26000000); +static DEF_PRCMU_CLK(sdmmcclk, PRCMU_SDMMCCLK, 50000000); +static DEF_PRCMU_CLK(spare1clk, PRCMU_SPARE1CLK, 50000000); +static DEF_PRCMU_CLK(per1clk, PRCMU_PER1CLK, 133330000); +static DEF_PRCMU_CLK(per2clk, PRCMU_PER2CLK, 133330000); +static DEF_PRCMU_CLK(per3clk, PRCMU_PER3CLK, 133330000); +static DEF_PRCMU_CLK(per5clk, PRCMU_PER5CLK, 133330000); +static DEF_PRCMU_CLK(per6clk, PRCMU_PER6CLK, 133330000); +static DEF_PRCMU_CLK(hdmiclk, PRCMU_HDMICLK, 26000000); +static DEF_PRCMU_CLK(apeatclk, PRCMU_APEATCLK, 200000000); +static DEF_PRCMU_CLK(apetraceclk, PRCMU_APETRACECLK, 266000000); +static DEF_PRCMU_CLK(mcdeclk, PRCMU_MCDECLK, 160000000); +static DEF_PRCMU_CLK(tvclk, PRCMU_TVCLK, 40000000); +static DEF_PRCMU_CLK(dsialtclk, PRCMU_DSIALTCLK, 400000000); +static DEF_PRCMU_CLK(timclk, PRCMU_TIMCLK, 3250000); +static DEF_PRCMU_CLK_PARENT(svaclk, PRCMU_SVACLK, 156000000, &soc1_pll); +static DEF_PRCMU_CLK(siaclk, PRCMU_SIACLK, 133330000); + +/* PRCC PClocks */ + +static DEF_PER1_PCLK(0, p1_pclk0); +static DEF_PER1_PCLK(1, p1_pclk1); +static DEF_PER1_PCLK(2, p1_pclk2); +static DEF_PER1_PCLK(3, p1_pclk3); +static DEF_PER1_PCLK(4, p1_pclk4); +static DEF_PER1_PCLK(5, p1_pclk5); +static DEF_PER1_PCLK(6, p1_pclk6); + +static DEF_PER2_PCLK(0, p2_pclk0); +static DEF_PER2_PCLK(1, p2_pclk1); + +static DEF_PER3_PCLK(0, p3_pclk0); +static DEF_PER3_PCLK(1, p3_pclk1); +static DEF_PER3_PCLK(2, p3_pclk2); + +static DEF_PER5_PCLK(0, p5_pclk0); +static DEF_PER5_PCLK(1, p5_pclk1); +static DEF_PER5_PCLK(2, p5_pclk2); +static DEF_PER5_PCLK(3, p5_pclk3); +static DEF_PER5_PCLK(4, p5_pclk4); +static DEF_PER5_PCLK(5, p5_pclk5); +static DEF_PER5_PCLK(6, p5_pclk6); +static DEF_PER5_PCLK(7, p5_pclk7); +static DEF_PER5_PCLK(8, p5_pclk8); +static DEF_PER5_PCLK(9, p5_pclk9); +static DEF_PER5_PCLK(10, p5_pclk10); +static DEF_PER5_PCLK(11, p5_pclk11); +static DEF_PER5_PCLK(12, p5_pclk12); +static DEF_PER5_PCLK(13, p5_pclk13); +static DEF_PER5_PCLK(14, p5_pclk14); +static DEF_PER5_PCLK(15, p5_pclk15); + +static DEF_PER6_PCLK(0, p6_pclk0); +static DEF_PER6_PCLK(1, p6_pclk1); +static DEF_PER6_PCLK(2, p6_pclk2); +static DEF_PER6_PCLK(3, p6_pclk3); +static DEF_PER6_PCLK(4, p6_pclk4); +static DEF_PER6_PCLK(5, p6_pclk5); +static DEF_PER6_PCLK(6, p6_pclk6); +static DEF_PER6_PCLK(7, p6_pclk7); + +/* MSP0 */ +static DEF_PER1_KCLK(0, p1_msp0_kclk, &msp02clk); +static DEF_PER_CLK(p1_msp0_clk, &p1_pclk0, &p1_msp0_kclk); + +/* SDI0 */ +static DEF_PER1_KCLK(1, p1_sdi0_kclk, &spare1clk); /* &sdmmcclk on v1 */ +static DEF_PER_CLK(p1_sdi0_clk, &p1_pclk1, &p1_sdi0_kclk); + +/* SDI2 */ +static DEF_PER1_KCLK(2, p1_sdi2_kclk, &sdmmcclk); +static DEF_PER_CLK(p1_sdi2_clk, &p1_pclk2, &p1_sdi2_kclk); + +/* UART0 */ +static DEF_PER1_KCLK(3, p1_uart0_kclk, &uartclk); +static DEF_PER_CLK(p1_uart0_clk, &p1_pclk3, &p1_uart0_kclk); + +/* I2C1 */ +static DEF_PER1_KCLK(4, p1_i2c1_kclk, &i2cclk); +static DEF_PER_CLK(p1_i2c1_clk, &p1_pclk4, &p1_i2c1_kclk); + +/* PWM */ +static DEF_PER3_KCLK(0, p3_pwm_kclk, &pwmclk); +static DEF_PER_CLK(p3_pwm_clk, &p3_pclk1, &p3_pwm_kclk); + +/* KEYPAD */ +static DEF_PER3_KCLK(0, p3_keypad_kclk, &kbd32k); +static DEF_PER_CLK(p3_keypad_clk, &p3_pclk0, &p3_keypad_kclk); + +/* MSP2 */ +static DEF_PER5_KCLK(0, p5_msp2_kclk, &msp02clk); +static DEF_PER_CLK(p5_msp2_clk, &p5_pclk0, &p5_msp2_kclk); + +/* UART1 */ +static DEF_PER5_KCLK(1, p5_uart1_kclk, &uartclk); +static DEF_PER_CLK(p5_uart1_clk, &p5_pclk1, &p5_uart1_kclk); + +/* UART2 */ +static DEF_PER5_KCLK(2, p5_uart2_kclk, &uartclk); +static DEF_PER_CLK(p5_uart2_clk, &p5_pclk2, &p5_uart2_kclk); + +/* UART3 */ +static DEF_PER5_KCLK(3, p5_uart3_kclk, &uartclk); +static DEF_PER_CLK(p5_uart3_clk, &p5_pclk3, &p5_uart3_kclk); + +/* SDI1 */ +static DEF_PER5_KCLK(4, p5_sdi1_kclk, &sdmmcclk); +static DEF_PER_CLK(p5_sdi1_clk, &p5_pclk4, &p5_sdi1_kclk); + +/* SDI3 */ +static DEF_PER5_KCLK(5, p5_sdi3_kclk, &sdmmcclk); +static DEF_PER_CLK(p5_sdi3_clk, &p5_pclk5, &p5_sdi3_kclk); + +/* SDI4 */ +static DEF_PER5_KCLK(6, p5_sdi4_kclk, &sdmmcclk); +static DEF_PER_CLK(p5_sdi4_clk, &p5_pclk6, &p5_sdi4_kclk); + +/* I2C2 */ +static DEF_PER5_KCLK(7, p5_i2c2_kclk, &i2cclk); +static DEF_PER_CLK(p5_i2c2_clk, &p5_pclk7, &p5_i2c2_kclk); + +/* I2C3 */ +static DEF_PER5_KCLK(8, p5_i2c3_kclk, &i2cclk); +static DEF_PER_CLK(p5_i2c3_clk, &p5_pclk8, &p5_i2c3_kclk); + +/* IRRC */ +static DEF_PER5_KCLK(9, p5_irrc_kclk, &irrcclk); +static DEF_PER_CLK(p5_irrc_clk, &p5_pclk9, &p5_irrc_kclk); + +/* IRDA */ +static DEF_PER5_KCLK(10, p5_irda_kclk, &irdaclk); +static DEF_PER_CLK(p5_irda_clk, &p5_pclk10, &p5_irda_kclk); + +/* RNG */ +static DEF_PER6_KCLK(0, p6_rng_kclk, &rngclk); +static DEF_PER_CLK(p6_rng_clk, &p6_pclk0, &p6_rng_kclk); + +/* MTU:S */ + +/* MTU0 */ +static DEF_PER_CLK(p6_mtu0_clk, &p6_pclk6, &timclk); + +/* MTU1 */ +static DEF_PER_CLK(p6_mtu1_clk, &p6_pclk7, &timclk); + +static struct clk *db5500_dbg_clks[] __initdata = { + /* Clock sources */ + &soc0_pll, + &soc1_pll, + &ddr_pll, + &sysclk, + &rtc32k, + + /* PRCMU clocks */ + &sgaclk, + &siaclk, + &svaclk, + &uartclk, + &msp02clk, + &msp1clk, + &cdclk, + &i2cclk, + &irdaclk, + &irrcclk, + &sdmmcclk, + &spare1clk, + &per1clk, + &per2clk, + &per3clk, + &per5clk, + &per6clk, + &hdmiclk, + &apeatclk, + &apetraceclk, + &mcdeclk, + &dsialtclk, + &dmaclk, + &b2r2clk, + &tvclk, + &rngclk, + &pwmclk, + + /* PRCC clocks */ + &p1_pclk0, + &p1_pclk1, + &p1_pclk2, + &p1_pclk3, + &p1_pclk4, + &p1_pclk5, + &p1_pclk6, + + &p2_pclk0, + &p2_pclk1, + + &p3_pclk0, + &p3_pclk1, + &p3_pclk2, + + &p5_pclk0, + &p5_pclk1, + &p5_pclk2, + &p5_pclk3, + &p5_pclk4, + &p5_pclk5, + &p5_pclk6, + &p5_pclk7, + &p5_pclk8, + &p5_pclk9, + &p5_pclk10, + &p5_pclk11, + &p5_pclk12, + &p5_pclk13, + &p5_pclk14, + &p5_pclk15, + + &p6_pclk0, + &p6_pclk1, + &p6_pclk2, + &p6_pclk3, + &p6_pclk4, + &p6_pclk5, + &p6_pclk6, + &p6_pclk7, + + /* Clock sources */ + &clkout0, + &clkout1, + &clkout2, + &rtc_clk1, +}; + +static struct clk_lookup u8500_common_clock_sources[] = { + CLK_LOOKUP(soc0_pll, NULL, "soc0_pll"), + CLK_LOOKUP(soc1_pll, NULL, "soc1_pll"), + CLK_LOOKUP(ddr_pll, NULL, "ddr_pll"), + CLK_LOOKUP(sysclk, NULL, "sysclk"), + CLK_LOOKUP(rtc32k, NULL, "clk32k"), +}; + +static struct clk_lookup db5500_prcmu_clocks[] = { + CLK_LOOKUP(sgaclk, "mali", NULL), + CLK_LOOKUP(siaclk, "mmio_camera", "sia"), + CLK_LOOKUP(svaclk, "hva", NULL), + CLK_LOOKUP(uartclk, "UART", NULL), + CLK_LOOKUP(msp02clk, "MSP02", NULL), + CLK_LOOKUP(msp1clk, "ux500-msp-i2s.1", NULL), + CLK_LOOKUP(cdclk, "cable_detect.0", NULL), + CLK_LOOKUP(i2cclk, "I2C", NULL), + CLK_LOOKUP(sdmmcclk, "sdmmc", NULL), + CLK_LOOKUP(per1clk, "PERIPH1", NULL), + CLK_LOOKUP(per2clk, "PERIPH2", NULL), + CLK_LOOKUP(per3clk, "PERIPH3", NULL), + CLK_LOOKUP(per5clk, "PERIPH5", NULL), + CLK_LOOKUP(per6clk, "PERIPH6", NULL), + CLK_LOOKUP(hdmiclk, "mcde", "hdmi"), + CLK_LOOKUP(apeatclk, "apeat", NULL), + CLK_LOOKUP(apetraceclk, "apetrace", NULL), + CLK_LOOKUP(mcdeclk, "mcde", NULL), + CLK_LOOKUP(mcdeclk, "mcde", "mcde"), + CLK_LOOKUP(dmaclk, "dma40.0", NULL), + CLK_LOOKUP(b2r2clk, "b2r2", NULL), + CLK_LOOKUP(b2r2clk, "b2r2_bus", NULL), + CLK_LOOKUP(b2r2clk, "U8500-B2R2.0", NULL), + CLK_LOOKUP(tvclk, "tv", NULL), + CLK_LOOKUP(tvclk, "mcde", "tv"), +}; + +static struct clk_lookup db5500_prcc_clocks[] = { + CLK_LOOKUP(p1_msp0_clk, "ux500-msp-i2s.0", NULL), + CLK_LOOKUP(p1_sdi0_clk, "sdi0", NULL), + CLK_LOOKUP(p1_sdi2_clk, "sdi2", NULL), + CLK_LOOKUP(p1_uart0_clk, "uart0", NULL), + CLK_LOOKUP(p1_i2c1_clk, "nmk-i2c.1", NULL), + CLK_LOOKUP(p1_pclk5, "gpio.0", NULL), + CLK_LOOKUP(p1_pclk5, "gpio.1", NULL), + CLK_LOOKUP(p1_pclk6, "fsmc", NULL), + + CLK_LOOKUP(p2_pclk0, "musb-ux500.0", "usb"), + CLK_LOOKUP(p2_pclk1, "gpio.2", NULL), + + CLK_LOOKUP(p3_keypad_clk, "db5500-keypad", NULL), + CLK_LOOKUP(p3_pwm_clk, "pwm", NULL), + CLK_LOOKUP(p3_pclk2, "gpio.4", NULL), + + CLK_LOOKUP(p5_msp2_clk, "ux500-msp-i2s.2", NULL), + CLK_LOOKUP(p5_uart1_clk, "uart1", NULL), + CLK_LOOKUP(p5_uart2_clk, "uart2", NULL), + CLK_LOOKUP(p5_uart3_clk, "uart3", NULL), + CLK_LOOKUP(p5_sdi1_clk, "sdi1", NULL), + CLK_LOOKUP(p5_sdi3_clk, "sdi3", NULL), + CLK_LOOKUP(p5_sdi4_clk, "sdi4", NULL), + CLK_LOOKUP(p5_i2c2_clk, "nmk-i2c.2", NULL), + CLK_LOOKUP(p5_i2c3_clk, "nmk-i2c.3", NULL), + CLK_LOOKUP(p5_irrc_clk, "irrc", NULL), + CLK_LOOKUP(p5_irda_clk, "irda", NULL), + CLK_LOOKUP(p5_pclk11, "spi0", NULL), + CLK_LOOKUP(p5_pclk12, "spi1", NULL), + CLK_LOOKUP(p5_pclk13, "spi2", NULL), + CLK_LOOKUP(p5_pclk14, "spi3", NULL), + CLK_LOOKUP(p5_pclk15, "gpio.5", NULL), + CLK_LOOKUP(p5_pclk15, "gpio.6", NULL), + CLK_LOOKUP(p5_pclk15, "gpio.7", NULL), + + CLK_LOOKUP(p6_rng_clk, "rng", NULL), + CLK_LOOKUP(p6_pclk1, "cryp0", NULL), + CLK_LOOKUP(p6_pclk2, "hash0", NULL), + CLK_LOOKUP(p6_pclk3, "pka", NULL), + CLK_LOOKUP(p6_pclk4, "hash1", NULL), + CLK_LOOKUP(p6_pclk1, "cryp1", NULL), + CLK_LOOKUP(p6_pclk5, "cfgreg", NULL), + CLK_LOOKUP(p6_mtu0_clk, "mtu0", NULL), + CLK_LOOKUP(p6_mtu1_clk, "mtu1", NULL), + + /* + * Dummy clock sets up the GPIOs. + */ + CLK_LOOKUP(clk_dummy, "gpio.3", NULL), + CLK_LOOKUP(rtc32k, "rtc-pl031", NULL), +}; + +static struct clk_lookup db5500_clkouts[] = { + CLK_LOOKUP(clkout1, "mmio_camera", "primary-cam"), + CLK_LOOKUP(clkout1, "mmio_camera", "secondary-cam"), + CLK_LOOKUP(clkout2, "ab5500-usb.0", "sysclk"), + CLK_LOOKUP(clkout2, "ab5500-codec.0", "sysclk"), +}; + +static struct clk_lookup u5500_clocks[] = { + CLK_LOOKUP(rtc_clk1, "cg2900-uart.0", "lpoclk"), +}; + +static const char *db5500_boot_clk[] __initdata = { + "spi0", + "spi1", + "spi2", + "spi3", + "uart0", + "uart1", + "uart2", + "uart3", + "sdi0", + "sdi1", + "sdi2", + "sdi3", + "sdi4", +}; + +static struct clk *boot_clks[ARRAY_SIZE(db5500_boot_clk)] __initdata; + +static int __init db5500_boot_clk_disable(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(db5500_boot_clk); i++) { + clk_disable(boot_clks[i]); + clk_put(boot_clks[i]); + } + + return 0; +} +late_initcall_sync(db5500_boot_clk_disable); + +static void __init db5500_boot_clk_enable(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(db5500_boot_clk); i++) { + boot_clks[i] = clk_get_sys(db5500_boot_clk[i], NULL); + BUG_ON(IS_ERR(boot_clks[i])); + clk_enable(boot_clks[i]); + } +} + +static void configure_clkouts(void) +{ + /* div parameter does not matter for sel0 REF_CLK */ + WARN_ON(prcmu_config_clkout(DB5500_CLKOUT0, + DB5500_CLKOUT_REF_CLK_SEL0, 0)); + WARN_ON(prcmu_config_clkout(DB5500_CLKOUT1, + DB5500_CLKOUT_REF_CLK_SEL0, 0)); +} + +static struct clk *db5500_clks_tobe_disabled[] __initdata = { + &siaclk, + &sgaclk, + &sdmmcclk, + &p1_pclk0, + &p1_pclk6, + &p3_keypad_clk, + &p3_pclk1, + &p5_pclk0, + &p5_pclk11, + &p5_pclk12, + &p5_pclk13, + &p5_pclk14, + &p6_pclk4, + &p6_pclk5, + &p6_pclk7, + &p5_uart1_clk, + &p5_uart2_clk, + &p5_uart3_clk, + &p5_sdi1_clk, + &p5_sdi3_clk, + &p5_sdi4_clk, + &p5_i2c3_clk, + &pwmclk, + &svaclk, + &cdclk, + &clkout2, +}; + +static int __init init_clock_states(void) +{ + int i = 0; + /* + * The following clks are shared with secure world. + * Currently this leads to a limitation where we need to + * enable them at all times. + */ + clk_enable(&p6_pclk1); + clk_enable(&p6_pclk2); + clk_enable(&p6_pclk3); + clk_enable(&p6_rng_clk); + + /* + * Disable clocks that are on at boot, but should be off. + */ + for (i = 0; i < ARRAY_SIZE(db5500_clks_tobe_disabled); i++) { + if (!clk_enable(db5500_clks_tobe_disabled[i])) + clk_disable(db5500_clks_tobe_disabled[i]); + } + return 0; +} +late_initcall(init_clock_states); + +int __init db5500_clk_init(void) +{ + if (ux500_is_svp()) { + prcmu_clk_ops.enable = NULL; + prcmu_clk_ops.disable = NULL; + prcc_pclk_ops.enable = NULL; + prcc_pclk_ops.disable = NULL; + prcc_kclk_ops.enable = NULL; + prcc_kclk_ops.disable = NULL; + } + prcmu_clk_ops.get_rate = NULL; + + clkdev_add_table(u8500_common_clock_sources, + ARRAY_SIZE(u8500_common_clock_sources)); + + clkdev_add_table(db5500_prcmu_clocks, ARRAY_SIZE(db5500_prcmu_clocks)); + clkdev_add_table(db5500_prcc_clocks, ARRAY_SIZE(db5500_prcc_clocks)); + clkdev_add_table(db5500_clkouts, ARRAY_SIZE(db5500_clkouts)); + clkdev_add_table(u5500_clocks, ARRAY_SIZE(u5500_clocks)); + + db5500_boot_clk_enable(); + + /* + * The following clks are shared with secure world. + * Currently this leads to a limitation where we need to + * enable them at all times. + */ + clk_enable(&p6_pclk1); + clk_enable(&p6_pclk2); + clk_enable(&p6_pclk3); + clk_enable(&p6_rng_clk); + + configure_clkouts(); + + return 0; +} + +int __init db5500_clk_debug_init(void) +{ + return dbx500_clk_debug_init(db5500_dbg_clks, + ARRAY_SIZE(db5500_dbg_clks)); +} diff --git a/arch/arm/mach-ux500/clock-db8500.c b/arch/arm/mach-ux500/clock-db8500.c new file mode 100644 index 00000000000..d41a22dd041 --- /dev/null +++ b/arch/arm/mach-ux500/clock-db8500.c @@ -0,0 +1,1171 @@ +/* + * Copyright (C) 2009-2011 ST-Ericsson SA + * Copyright (C) 2009 STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/init.h> +#include <linux/list.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/errno.h> +#include <linux/mutex.h> +#include <linux/delay.h> +#include <linux/seq_file.h> +#include <linux/uaccess.h> +#include <linux/debugfs.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <linux/gpio/nomadik.h> +#include <linux/mfd/abx500/ab8500-sysctrl.h> +#include <linux/workqueue.h> +#include <linux/regulator/consumer.h> + +#include <plat/pincfg.h> + +#include <mach/hardware.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include "clock.h" +#include "pins-db8500.h" +#include "product.h" +#include "prcc.h" + +static DEFINE_MUTEX(soc0_pll_mutex); +static DEFINE_MUTEX(soc1_pll_mutex); +static DEFINE_MUTEX(sysclk_mutex); +static DEFINE_MUTEX(ab_ulpclk_mutex); +static DEFINE_MUTEX(ab_intclk_mutex); +static DEFINE_MUTEX(clkout0_mutex); +static DEFINE_MUTEX(dsi_pll_mutex); + +static struct delayed_work sysclk_disable_work; + +/* PLL operations. */ + +static unsigned long pll_get_rate(struct clk *clk) +{ + return prcmu_clock_rate(clk->cg_sel); +} + +static struct clkops pll_ops = { + .get_rate = pll_get_rate, +}; + +/* SysClk operations. */ + +static int request_sysclk(bool enable) +{ + static int requests; + + if ((enable && (requests++ == 0)) || (!enable && (--requests == 0))) + return prcmu_request_clock(PRCMU_SYSCLK, enable); + return 0; +} + +static int sysclk_enable(struct clk *clk) +{ + static bool swat_enable; + int r; + + if (!swat_enable) { + r = ab8500_sysctrl_set(AB8500_SWATCTRL, + AB8500_SWATCTRL_SWATENABLE); + if (r) + return r; + + swat_enable = true; + } + + r = request_sysclk(true); + if (r) + return r; + + if (clk->cg_sel) { + r = ab8500_sysctrl_set(AB8500_SYSULPCLKCTRL1, (u8)clk->cg_sel); + if (r) + (void)request_sysclk(false); + } + return r; +} + +static void sysclk_disable(struct clk *clk) +{ + int r; + + if (clk->cg_sel) { + r = ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, + (u8)clk->cg_sel); + if (r) + goto disable_failed; + } + r = request_sysclk(false); + if (r) + goto disable_failed; + return; + +disable_failed: + pr_err("clock: failed to disable %s.\n", clk->name); +} + +static struct clkops sysclk_ops = { + .enable = sysclk_enable, + .disable = sysclk_disable, +}; + +/* AB8500 UlpClk operations */ + +static int ab_ulpclk_enable(struct clk *clk) +{ + int err; + + if (clk->regulator == NULL) { + struct regulator *reg; + + reg = regulator_get(NULL, "v-intcore"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + clk->regulator = reg; + } + err = regulator_set_optimum_mode(clk->regulator, 1500); + if (unlikely(err < 0)) + goto regulator_enable_error; + err = regulator_enable(clk->regulator); + if (unlikely(err)) + goto regulator_enable_error; + err = ab8500_sysctrl_clear(AB8500_SYSULPCLKCONF, + AB8500_SYSULPCLKCONF_ULPCLKCONF_MASK); + if (unlikely(err)) + goto enable_error; + err = ab8500_sysctrl_set(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_ULPCLKREQ); + if (unlikely(err)) + goto enable_error; + /* Unknown/undocumented PLL locking time => wait 1 ms. */ + mdelay(1); + return 0; + +enable_error: + (void)regulator_disable(clk->regulator); +regulator_enable_error: + return err; +} + +static void ab_ulpclk_disable(struct clk *clk) +{ + int err; + + err = ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_ULPCLKREQ); + if (unlikely(regulator_disable(clk->regulator) || err)) + goto out_err; + + regulator_set_optimum_mode(clk->regulator, 0); + + return; + +out_err: + pr_err("clock: %s failed to disable %s.\n", __func__, clk->name); +} + +static struct clkops ab_ulpclk_ops = { + .enable = ab_ulpclk_enable, + .disable = ab_ulpclk_disable, +}; + +/* AB8500 intclk operations */ + +enum ab_intclk_parent { + AB_INTCLK_PARENT_SYSCLK, + AB_INTCLK_PARENT_ULPCLK, + AB_INTCLK_PARENTS_END, + NUM_AB_INTCLK_PARENTS +}; + +static int ab_intclk_enable(struct clk *clk) +{ + if (clk->parent == clk->parents[AB_INTCLK_PARENT_ULPCLK]) { + return ab8500_sysctrl_write(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK, + (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT)); + } + return 0; +} + +static void ab_intclk_disable(struct clk *clk) +{ + if (clk->parent == clk->parents[AB_INTCLK_PARENT_SYSCLK]) + return; + + if (ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK)) { + pr_err("clock: %s failed to disable %s.\n", __func__, + clk->name); + } +} + +static int ab_intclk_set_parent(struct clk *clk, struct clk *parent) +{ + int err; + + if (!clk->enabled) + return 0; + + err = __clk_enable(parent, clk->mutex); + + if (unlikely(err)) + goto parent_enable_error; + + if (parent == clk->parents[AB_INTCLK_PARENT_ULPCLK]) { + err = ab8500_sysctrl_write(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK, + (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT)); + } else { + err = ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK); + } + if (unlikely(err)) + goto config_error; + + __clk_disable(clk->parent, clk->mutex); + + return 0; + +config_error: + __clk_disable(parent, clk->mutex); +parent_enable_error: + return err; +} + +static struct clkops ab_intclk_ops = { + .enable = ab_intclk_enable, + .disable = ab_intclk_disable, + .set_parent = ab_intclk_set_parent, +}; + +/* AB8500 audio clock operations */ + +static int audioclk_enable(struct clk *clk) +{ + return ab8500_sysctrl_set(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_AUDIOCLKENA); +} + +static void audioclk_disable(struct clk *clk) +{ + if (ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, + AB8500_SYSULPCLKCTRL1_AUDIOCLKENA)) { + pr_err("clock: %s failed to disable %s.\n", __func__, + clk->name); + } +} + +static struct clkops audioclk_ops = { + .enable = audioclk_enable, + .disable = audioclk_disable, +}; + +/* Primary camera clock operations */ +static int clkout0_enable(struct clk *clk) +{ + int r; + + if (clk->regulator == NULL) { + struct regulator *reg; + + reg = regulator_get(NULL, "v-ape"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + clk->regulator = reg; + } + r = regulator_enable(clk->regulator); + if (r) + goto regulator_failed; + r = prcmu_config_clkout(0, PRCMU_CLKSRC_CLK38M, 4); + if (r) + goto config_failed; + r = nmk_config_pin(GPIO227_CLKOUT1, false); + if (r) + goto gpio_failed; + return r; + +gpio_failed: + (void)prcmu_config_clkout(0, PRCMU_CLKSRC_CLK38M, 0); +config_failed: + (void)regulator_disable(clk->regulator); +regulator_failed: + return r; +} + +static void clkout0_disable(struct clk *clk) +{ + int r; + + r = nmk_config_pin((GPIO227_GPIO | PIN_OUTPUT_LOW), false); + if (r) + goto disable_failed; + (void)prcmu_config_clkout(0, PRCMU_CLKSRC_CLK38M, 0); + (void)regulator_disable(clk->regulator); + return; + +disable_failed: + pr_err("clock: failed to disable %s.\n", clk->name); +} + +/* Touch screen/secondary camera clock operations. */ +static int clkout1_enable(struct clk *clk) +{ + int r; + + if (clk->regulator == NULL) { + struct regulator *reg; + + reg = regulator_get(NULL, "v-ape"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + clk->regulator = reg; + } + r = regulator_enable(clk->regulator); + if (r) + goto regulator_failed; + r = prcmu_config_clkout(1, PRCMU_CLKSRC_SYSCLK, 4); + if (r) + goto config_failed; + r = nmk_config_pin(GPIO228_CLKOUT2, false); + if (r) + goto gpio_failed; + return r; + +gpio_failed: + (void)prcmu_config_clkout(1, PRCMU_CLKSRC_SYSCLK, 0); +config_failed: + (void)regulator_disable(clk->regulator); +regulator_failed: + return r; +} + +static void clkout1_disable(struct clk *clk) +{ + int r; + + r = nmk_config_pin((GPIO228_GPIO | PIN_OUTPUT_LOW), false); + if (r) + goto disable_failed; + (void)prcmu_config_clkout(1, PRCMU_CLKSRC_SYSCLK, 0); + (void)regulator_disable(clk->regulator); + return; + +disable_failed: + pr_err("clock: failed to disable %s.\n", clk->name); +} + +static struct clkops clkout0_ops = { + .enable = clkout0_enable, + .disable = clkout0_disable, +}; + +static struct clkops clkout1_ops = { + .enable = clkout1_enable, + .disable = clkout1_disable, +}; + +#define DEF_PER1_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U8500_CLKRST1_BASE, _cg_bit, &per1clk) +#define DEF_PER2_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U8500_CLKRST2_BASE, _cg_bit, &per2clk) +#define DEF_PER3_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U8500_CLKRST3_BASE, _cg_bit, &per3clk) +#define DEF_PER5_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U8500_CLKRST5_BASE, _cg_bit, &per5clk) +#define DEF_PER6_PCLK(_cg_bit, _name) \ + DEF_PRCC_PCLK(_name, U8500_CLKRST6_BASE, _cg_bit, &per6clk) + +#define DEF_PER1_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U8500_CLKRST1_BASE, _cg_bit, _parent, &per1clk) +#define DEF_PER2_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U8500_CLKRST2_BASE, _cg_bit, _parent, &per2clk) +#define DEF_PER3_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U8500_CLKRST3_BASE, _cg_bit, _parent, &per3clk) +#define DEF_PER5_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U8500_CLKRST5_BASE, _cg_bit, _parent, &per5clk) +#define DEF_PER6_KCLK(_cg_bit, _name, _parent) \ + DEF_PRCC_KCLK(_name, U8500_CLKRST6_BASE, _cg_bit, _parent, &per6clk) + +/* Clock sources. */ + +static struct clk soc0_pll = { + .name = "soc0_pll", + .ops = &prcmu_clk_ops, + .cg_sel = PRCMU_PLLSOC0, + .mutex = &soc0_pll_mutex, +}; + +static struct clk soc1_pll = { + .name = "soc1_pll", + .ops = &prcmu_clk_ops, + .cg_sel = PRCMU_PLLSOC1, + .mutex = &soc1_pll_mutex, +}; + +static struct clk ddr_pll = { + .name = "ddr_pll", + .ops = &pll_ops, + .cg_sel = PRCMU_PLLDDR, +}; + +static struct clk ulp38m4 = { + .name = "ulp38m4", + .rate = 38400000, +}; + +static struct clk sysclk = { + .name = "sysclk", + .ops = &sysclk_ops, + .rate = 38400000, + .mutex = &sysclk_mutex, +}; + +static struct clk sysclk2 = { + .name = "sysclk2", + .ops = &sysclk_ops, + .cg_sel = AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, + .rate = 38400000, + .mutex = &sysclk_mutex, +}; + +static struct clk sysclk3 = { + .name = "sysclk3", + .ops = &sysclk_ops, + .cg_sel = AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, + .rate = 38400000, + .mutex = &sysclk_mutex, +}; + +static struct clk sysclk4 = { + .name = "sysclk4", + .ops = &sysclk_ops, + .cg_sel = AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, + .rate = 38400000, + .mutex = &sysclk_mutex, +}; + +static struct clk rtc32k = { + .name = "rtc32k", + .rate = 32768, +}; + +static struct clk clkout0 = { + .name = "clkout0", + .ops = &clkout0_ops, + .parent = &ulp38m4, + .rate = 9600000, + .mutex = &clkout0_mutex, +}; + +static struct clk clkout1 = { + .name = "clkout1", + .ops = &clkout1_ops, + .parent = &sysclk, + .rate = 9600000, + .mutex = &sysclk_mutex, +}; + +static struct clk ab_ulpclk = { + .name = "ab_ulpclk", + .ops = &ab_ulpclk_ops, + .rate = 38400000, + .mutex = &ab_ulpclk_mutex, +}; + +static struct clk *ab_intclk_parents[NUM_AB_INTCLK_PARENTS] = { + [AB_INTCLK_PARENT_SYSCLK] = &sysclk, + [AB_INTCLK_PARENT_ULPCLK] = &ab_ulpclk, + [AB_INTCLK_PARENTS_END] = NULL, +}; + +static struct clk ab_intclk = { + .name = "ab_intclk", + .ops = &ab_intclk_ops, + .mutex = &ab_intclk_mutex, + .parent = &sysclk, + .parents = ab_intclk_parents, +}; + +static struct clk audioclk = { + .name = "audioclk", + .ops = &audioclk_ops, + .mutex = &ab_intclk_mutex, + .parent = &ab_intclk, +}; + +static DEF_PRCMU_CLK(sgaclk, PRCMU_SGACLK, 320000000); +static DEF_PRCMU_CLK(uartclk, PRCMU_UARTCLK, 38400000); +static DEF_PRCMU_CLK(msp02clk, PRCMU_MSP02CLK, 19200000); +static DEF_PRCMU_CLK(msp1clk, PRCMU_MSP1CLK, 19200000); +static DEF_PRCMU_CLK(i2cclk, PRCMU_I2CCLK, 24000000); +static DEF_PRCMU_CLK(slimclk, PRCMU_SLIMCLK, 19200000); +static DEF_PRCMU_CLK(per1clk, PRCMU_PER1CLK, 133330000); +static DEF_PRCMU_CLK(per2clk, PRCMU_PER2CLK, 133330000); +static DEF_PRCMU_CLK(per3clk, PRCMU_PER3CLK, 133330000); +static DEF_PRCMU_CLK(per5clk, PRCMU_PER5CLK, 133330000); +static DEF_PRCMU_CLK(per6clk, PRCMU_PER6CLK, 133330000); +static DEF_PRCMU_CLK(per7clk, PRCMU_PER7CLK, 100000000); +static DEF_PRCMU_SCALABLE_CLK(lcdclk, PRCMU_LCDCLK); +static DEF_PRCMU_OPP100_CLK(bmlclk, PRCMU_BMLCLK, 200000000); +static DEF_PRCMU_SCALABLE_CLK(hsitxclk, PRCMU_HSITXCLK); +static DEF_PRCMU_SCALABLE_CLK(hsirxclk, PRCMU_HSIRXCLK); +static DEF_PRCMU_SCALABLE_CLK(hdmiclk, PRCMU_HDMICLK); +static DEF_PRCMU_CLK(apeatclk, PRCMU_APEATCLK, 160000000); +static DEF_PRCMU_CLK(apetraceclk, PRCMU_APETRACECLK, 160000000); +static DEF_PRCMU_CLK(mcdeclk, PRCMU_MCDECLK, 160000000); +static DEF_PRCMU_OPP100_CLK(ipi2cclk, PRCMU_IPI2CCLK, 24000000); +static DEF_PRCMU_CLK(dsialtclk, PRCMU_DSIALTCLK, 384000000); +static DEF_PRCMU_CLK(dmaclk, PRCMU_DMACLK, 200000000); +static DEF_PRCMU_CLK(b2r2clk, PRCMU_B2R2CLK, 200000000); +static DEF_PRCMU_SCALABLE_CLK(tvclk, PRCMU_TVCLK); +/* TODO: For SSPCLK, the spec says 24MHz, while the old driver says 48MHz. */ +static DEF_PRCMU_CLK(sspclk, PRCMU_SSPCLK, 24000000); +static DEF_PRCMU_CLK(rngclk, PRCMU_RNGCLK, 19200000); +static DEF_PRCMU_CLK(uiccclk, PRCMU_UICCCLK, 48000000); +static DEF_PRCMU_CLK(timclk, PRCMU_TIMCLK, 2400000); +static DEF_PRCMU_CLK(sdmmcclk, PRCMU_SDMMCCLK, 50000000); + +static struct clk dsi_pll = { + .name = "dsi_pll", + .ops = &prcmu_scalable_clk_ops, + .cg_sel = PRCMU_PLLDSI, + .parent = &hdmiclk, + .mutex = &dsi_pll_mutex, +}; + +static struct clk dsi0clk = { + .name = "dsi0clk", + .ops = &prcmu_scalable_clk_ops, + .cg_sel = PRCMU_DSI0CLK, + .parent = &dsi_pll, + .mutex = &dsi_pll_mutex, +}; + +static struct clk dsi1clk = { + .name = "dsi1clk", + .ops = &prcmu_scalable_clk_ops, + .cg_sel = PRCMU_DSI1CLK, + .parent = &dsi_pll, + .mutex = &dsi_pll_mutex, +}; + +static struct clk dsi0escclk = { + .name = "dsi0escclk", + .ops = &prcmu_scalable_clk_ops, + .cg_sel = PRCMU_DSI0ESCCLK, + .parent = &tvclk, +}; + +static struct clk dsi1escclk = { + .name = "dsi1escclk", + .ops = &prcmu_scalable_clk_ops, + .cg_sel = PRCMU_DSI1ESCCLK, + .parent = &tvclk, +}; + +static struct clk dsi2escclk = { + .name = "dsi2escclk", + .ops = &prcmu_scalable_clk_ops, + .cg_sel = PRCMU_DSI2ESCCLK, + .parent = &tvclk, +}; + +/* PRCC PClocks */ + +static DEF_PER1_PCLK(0, p1_pclk0); +static DEF_PER1_PCLK(1, p1_pclk1); +static DEF_PER1_PCLK(2, p1_pclk2); +static DEF_PER1_PCLK(3, p1_pclk3); +static DEF_PER1_PCLK(4, p1_pclk4); +static DEF_PER1_PCLK(5, p1_pclk5); +static DEF_PER1_PCLK(6, p1_pclk6); +static DEF_PER1_PCLK(7, p1_pclk7); +static DEF_PER1_PCLK(8, p1_pclk8); +static DEF_PER1_PCLK(9, p1_pclk9); +static DEF_PER1_PCLK(10, p1_pclk10); +static DEF_PER1_PCLK(11, p1_pclk11); + +static DEF_PER2_PCLK(0, p2_pclk0); +static DEF_PER2_PCLK(1, p2_pclk1); +static DEF_PER2_PCLK(2, p2_pclk2); +static DEF_PER2_PCLK(3, p2_pclk3); +static DEF_PER2_PCLK(4, p2_pclk4); +static DEF_PER2_PCLK(5, p2_pclk5); +static DEF_PER2_PCLK(6, p2_pclk6); +static DEF_PER2_PCLK(7, p2_pclk7); +static DEF_PER2_PCLK(8, p2_pclk8); +static DEF_PER2_PCLK(9, p2_pclk9); +static DEF_PER2_PCLK(10, p2_pclk10); +static DEF_PER2_PCLK(11, p2_pclk11); + +static DEF_PER3_PCLK(0, p3_pclk0); +static DEF_PER3_PCLK(1, p3_pclk1); +static DEF_PER3_PCLK(2, p3_pclk2); +static DEF_PER3_PCLK(3, p3_pclk3); +static DEF_PER3_PCLK(4, p3_pclk4); +static DEF_PER3_PCLK(5, p3_pclk5); +static DEF_PER3_PCLK(6, p3_pclk6); +static DEF_PER3_PCLK(7, p3_pclk7); +static DEF_PER3_PCLK(8, p3_pclk8); + +static DEF_PER5_PCLK(0, p5_pclk0); +static DEF_PER5_PCLK(1, p5_pclk1); + +static DEF_PER6_PCLK(0, p6_pclk0); +static DEF_PER6_PCLK(1, p6_pclk1); +static DEF_PER6_PCLK(2, p6_pclk2); +static DEF_PER6_PCLK(3, p6_pclk3); +static DEF_PER6_PCLK(4, p6_pclk4); +static DEF_PER6_PCLK(5, p6_pclk5); +static DEF_PER6_PCLK(6, p6_pclk6); +static DEF_PER6_PCLK(7, p6_pclk7); + +/* UART0 */ +static DEF_PER1_KCLK(0, p1_uart0_kclk, &uartclk); +static DEF_PER_CLK(p1_uart0_clk, &p1_pclk0, &p1_uart0_kclk); + +/* UART1 */ +static DEF_PER1_KCLK(1, p1_uart1_kclk, &uartclk); +static DEF_PER_CLK(p1_uart1_clk, &p1_pclk1, &p1_uart1_kclk); + +/* I2C1 */ +static DEF_PER1_KCLK(2, p1_i2c1_kclk, &i2cclk); +static DEF_PER_CLK(p1_i2c1_clk, &p1_pclk2, &p1_i2c1_kclk); + +/* MSP0 */ +static DEF_PER1_KCLK(3, p1_msp0_kclk, &msp02clk); +static DEF_PER_CLK(p1_msp0_clk, &p1_pclk3, &p1_msp0_kclk); + +/* MSP1 */ +static DEF_PER1_KCLK(4, p1_msp1_kclk, &msp1clk); +static DEF_PER_CLK(p1_msp1_clk, &p1_pclk4, &p1_msp1_kclk); + +/* SDI0 */ +static DEF_PER1_KCLK(5, p1_sdi0_kclk, &sdmmcclk); +static DEF_PER_CLK(p1_sdi0_clk, &p1_pclk5, &p1_sdi0_kclk); + +/* I2C2 */ +static DEF_PER1_KCLK(6, p1_i2c2_kclk, &i2cclk); +static DEF_PER_CLK(p1_i2c2_clk, &p1_pclk6, &p1_i2c2_kclk); + +/* SLIMBUS0 */ +static DEF_PER1_KCLK(3, p1_slimbus0_kclk, &slimclk); +static DEF_PER_CLK(p1_slimbus0_clk, &p1_pclk8, &p1_slimbus0_kclk); + +/* I2C4 */ +static DEF_PER1_KCLK(9, p1_i2c4_kclk, &i2cclk); +static DEF_PER_CLK(p1_i2c4_clk, &p1_pclk10, &p1_i2c4_kclk); + +/* MSP3 */ +static DEF_PER1_KCLK(10, p1_msp3_kclk, &msp1clk); +static DEF_PER_CLK(p1_msp3_clk, &p1_pclk11, &p1_msp3_kclk); + +/* I2C3 */ +static DEF_PER2_KCLK(0, p2_i2c3_kclk, &i2cclk); +static DEF_PER_CLK(p2_i2c3_clk, &p2_pclk0, &p2_i2c3_kclk); + +/* SDI4 */ +static DEF_PER2_KCLK(2, p2_sdi4_kclk, &sdmmcclk); +static DEF_PER_CLK(p2_sdi4_clk, &p2_pclk4, &p2_sdi4_kclk); + +/* MSP2 */ +static DEF_PER2_KCLK(3, p2_msp2_kclk, &msp02clk); +static DEF_PER_CLK(p2_msp2_clk, &p2_pclk5, &p2_msp2_kclk); + +/* SDI1 */ +static DEF_PER2_KCLK(4, p2_sdi1_kclk, &sdmmcclk); +static DEF_PER_CLK(p2_sdi1_clk, &p2_pclk6, &p2_sdi1_kclk); + +/* SDI3 */ +static DEF_PER2_KCLK(5, p2_sdi3_kclk, &sdmmcclk); +static DEF_PER_CLK(p2_sdi3_clk, &p2_pclk7, &p2_sdi3_kclk); + +/* HSIR */ +static struct clk p2_ssirx_kclk = { + .name = "p2_ssirx_kclk", + .ops = &prcc_kclk_rec_ops, + .io_base = U8500_CLKRST2_BASE, + .cg_sel = BIT(6), + .parent = &hsirxclk, + .clock = &per2clk, +}; + +/* HSIT */ +static struct clk p2_ssitx_kclk = { + .name = "p2_ssitx_kclk", + .ops = &prcc_kclk_rec_ops, + .io_base = U8500_CLKRST2_BASE, + .cg_sel = BIT(7), + .parent = &hsitxclk, + .clock = &per2clk, +}; + +/* SSP0 */ +static DEF_PER3_KCLK(1, p3_ssp0_kclk, &sspclk); +static DEF_PER_CLK(p3_ssp0_clk, &p3_pclk1, &p3_ssp0_kclk); + +/* SSP1 */ +static DEF_PER3_KCLK(2, p3_ssp1_kclk, &sspclk); +static DEF_PER_CLK(p3_ssp1_clk, &p3_pclk2, &p3_ssp1_kclk); + +/* I2C0 */ +static DEF_PER3_KCLK(3, p3_i2c0_kclk, &i2cclk); +static DEF_PER_CLK(p3_i2c0_clk, &p3_pclk3, &p3_i2c0_kclk); + +/* SDI2 */ +static DEF_PER3_KCLK(4, p3_sdi2_kclk, &sdmmcclk); +static DEF_PER_CLK(p3_sdi2_clk, &p3_pclk4, &p3_sdi2_kclk); + +/* SKE */ +static DEF_PER3_KCLK(5, p3_ske_kclk, &rtc32k); +static DEF_PER_CLK(p3_ske_clk, &p3_pclk5, &p3_ske_kclk); + +/* UART2 */ +static DEF_PER3_KCLK(6, p3_uart2_kclk, &uartclk); +static DEF_PER_CLK(p3_uart2_clk, &p3_pclk6, &p3_uart2_kclk); + +/* SDI5 */ +static DEF_PER3_KCLK(7, p3_sdi5_kclk, &sdmmcclk); +static DEF_PER_CLK(p3_sdi5_clk, &p3_pclk7, &p3_sdi5_kclk); + +/* RNG */ +static DEF_PER6_KCLK(0, p6_rng_kclk, &rngclk); +static DEF_PER_CLK(p6_rng_clk, &p6_pclk0, &p6_rng_kclk); + +/* MTU:S */ + +/* MTU0 */ +static DEF_PER_CLK(p6_mtu0_clk, &p6_pclk6, &timclk); + +/* MTU1 */ +static DEF_PER_CLK(p6_mtu1_clk, &p6_pclk7, &timclk); + +/* + * TODO: Ensure names match with devices and then remove unnecessary entries + * when all drivers use the clk API. + */ + +static struct clk_lookup u8500_clocks[] = { + CLK_LOOKUP(soc0_pll, NULL, "soc0_pll"), + CLK_LOOKUP(soc1_pll, NULL, "soc1_pll"), + CLK_LOOKUP(ddr_pll, NULL, "ddr_pll"), + CLK_LOOKUP(ulp38m4, NULL, "ulp38m4"), + CLK_LOOKUP(sysclk, NULL, "sysclk"), + CLK_LOOKUP(rtc32k, NULL, "clk32k"), + CLK_LOOKUP(sysclk, "ab8500-usb.0", "sysclk"), + CLK_LOOKUP(sysclk, "ab8500-codec.0", "sysclk"), + CLK_LOOKUP(ab_ulpclk, "ab8500-codec.0", "ulpclk"), + CLK_LOOKUP(ab_intclk, "ab8500-codec.0", "intclk"), + CLK_LOOKUP(audioclk, "ab8500-codec.0", "audioclk"), + CLK_LOOKUP(ab_intclk, "ab8500-pwm.1", NULL), + + CLK_LOOKUP(clkout0, "pri-cam", NULL), + CLK_LOOKUP(clkout1, "3-005c", NULL), + CLK_LOOKUP(clkout1, "3-005d", NULL), + CLK_LOOKUP(clkout1, "sec-cam", NULL), + + /* prcmu */ + CLK_LOOKUP(sgaclk, "mali", NULL), + CLK_LOOKUP(uartclk, "UART", NULL), + CLK_LOOKUP(msp02clk, "MSP02", NULL), + CLK_LOOKUP(i2cclk, "I2C", NULL), + CLK_LOOKUP(sdmmcclk, "sdmmc", NULL), + CLK_LOOKUP(slimclk, "slim", NULL), + CLK_LOOKUP(per1clk, "PERIPH1", NULL), + CLK_LOOKUP(per2clk, "PERIPH2", NULL), + CLK_LOOKUP(per3clk, "PERIPH3", NULL), + CLK_LOOKUP(per5clk, "PERIPH5", NULL), + CLK_LOOKUP(per6clk, "PERIPH6", NULL), + CLK_LOOKUP(per7clk, "PERIPH7", NULL), + CLK_LOOKUP(lcdclk, "lcd", NULL), + CLK_LOOKUP(bmlclk, "bml", NULL), + CLK_LOOKUP(p2_ssitx_kclk, "ste_hsi.0", "hsit_hsitxclk"), + CLK_LOOKUP(p2_ssirx_kclk, "ste_hsi.0", "hsir_hsirxclk"), + CLK_LOOKUP(lcdclk, "mcde", "lcd"), + CLK_LOOKUP(hdmiclk, "hdmi", NULL), + CLK_LOOKUP(hdmiclk, "mcde", "hdmi"), + CLK_LOOKUP(apeatclk, "apeat", NULL), + CLK_LOOKUP(apetraceclk, "apetrace", NULL), + CLK_LOOKUP(mcdeclk, "mcde", NULL), + CLK_LOOKUP(mcdeclk, "mcde", "mcde"), + CLK_LOOKUP(ipi2cclk, "ipi2", NULL), + CLK_LOOKUP(dmaclk, "dma40.0", NULL), + CLK_LOOKUP(b2r2clk, "b2r2", NULL), + CLK_LOOKUP(b2r2clk, "b2r2_core", NULL), + CLK_LOOKUP(b2r2clk, "U8500-B2R2.0", NULL), + CLK_LOOKUP(tvclk, "tv", NULL), + CLK_LOOKUP(tvclk, "mcde", "tv"), + CLK_LOOKUP(msp1clk, "MSP1", NULL), + CLK_LOOKUP(dsialtclk, "dsialt", NULL), + CLK_LOOKUP(sspclk, "SSP", NULL), + CLK_LOOKUP(rngclk, "rngclk", NULL), + CLK_LOOKUP(uiccclk, "uicc", NULL), + CLK_LOOKUP(dsi0clk, "mcde", "dsihs0"), + CLK_LOOKUP(dsi1clk, "mcde", "dsihs1"), + CLK_LOOKUP(dsi_pll, "mcde", "dsihs2"), + CLK_LOOKUP(dsi0escclk, "mcde", "dsilp0"), + CLK_LOOKUP(dsi1escclk, "mcde", "dsilp1"), + CLK_LOOKUP(dsi2escclk, "mcde", "dsilp2"), + + /* PERIPH 1 */ + CLK_LOOKUP(p1_msp3_clk, "msp3", NULL), + CLK_LOOKUP(p1_msp3_clk, "ux500-msp-i2s.3", NULL), + CLK_LOOKUP(p1_msp3_kclk, "ab8500-codec.0", "msp3-kernel"), + CLK_LOOKUP(p1_pclk11, "ab8500-codec.0", "msp3-bus"), + CLK_LOOKUP(p1_uart0_clk, "uart0", NULL), + CLK_LOOKUP(p1_uart1_clk, "uart1", NULL), + CLK_LOOKUP(p1_i2c1_clk, "nmk-i2c.1", NULL), + CLK_LOOKUP(p1_msp0_clk, "msp0", NULL), + CLK_LOOKUP(p1_msp0_clk, "ux500-msp-i2s.0", NULL), + CLK_LOOKUP(p1_sdi0_clk, "sdi0", NULL), + CLK_LOOKUP(p1_i2c2_clk, "nmk-i2c.2", NULL), + CLK_LOOKUP(p1_slimbus0_clk, "slimbus0", NULL), + CLK_LOOKUP(p1_pclk9, "gpio.0", NULL), + CLK_LOOKUP(p1_pclk9, "gpio.1", NULL), + CLK_LOOKUP(p1_pclk9, "gpioblock0", NULL), + CLK_LOOKUP(p1_msp1_clk, "msp1", NULL), + CLK_LOOKUP(p1_msp1_clk, "ux500-msp-i2s.1", NULL), + CLK_LOOKUP(p1_msp1_kclk, "ab8500-codec.0", "msp1-kernel"), + CLK_LOOKUP(p1_pclk4, "ab8500-codec.0", "msp1-bus"), + CLK_LOOKUP(p1_pclk7, "spi3", NULL), + CLK_LOOKUP(p1_i2c4_clk, "nmk-i2c.4", NULL), + + /* PERIPH 2 */ + CLK_LOOKUP(p2_i2c3_clk, "nmk-i2c.3", NULL), + CLK_LOOKUP(p2_pclk1, "spi2", NULL), + CLK_LOOKUP(p2_pclk2, "spi1", NULL), + CLK_LOOKUP(p2_pclk3, "pwl", NULL), + CLK_LOOKUP(p2_sdi4_clk, "sdi4", NULL), + CLK_LOOKUP(p2_msp2_clk, "msp2", NULL), + CLK_LOOKUP(p2_msp2_clk, "ux500-msp-i2s.2", NULL), + CLK_LOOKUP(p2_sdi1_clk, "sdi1", NULL), + CLK_LOOKUP(p2_sdi3_clk, "sdi3", NULL), + CLK_LOOKUP(p2_pclk8, "spi0", NULL), + CLK_LOOKUP(p2_pclk9, "ste_hsi.0", "hsir_hclk"), + CLK_LOOKUP(p2_pclk10, "ste_hsi.0", "hsit_hclk"), + CLK_LOOKUP(p2_pclk11, "gpio.6", NULL), + CLK_LOOKUP(p2_pclk11, "gpio.7", NULL), + CLK_LOOKUP(p2_pclk11, "gpioblock1", NULL), + + /* PERIPH 3 */ + CLK_LOOKUP(p3_pclk0, NULL, "fsmc"), + CLK_LOOKUP(p3_i2c0_clk, "nmk-i2c.0", NULL), + CLK_LOOKUP(p3_sdi2_clk, "sdi2", NULL), + CLK_LOOKUP(p3_ske_clk, "ske", NULL), + CLK_LOOKUP(p3_ske_clk, "nmk-ske-keypad", NULL), + CLK_LOOKUP(p3_uart2_clk, "uart2", NULL), + CLK_LOOKUP(p3_sdi5_clk, "sdi5", NULL), + CLK_LOOKUP(p3_pclk8, "gpio.2", NULL), + CLK_LOOKUP(p3_pclk8, "gpio.3", NULL), + CLK_LOOKUP(p3_pclk8, "gpio.4", NULL), + CLK_LOOKUP(p3_pclk8, "gpio.5", NULL), + CLK_LOOKUP(p3_pclk8, "gpioblock2", NULL), + CLK_LOOKUP(p3_ssp0_clk, "ssp0", NULL), + CLK_LOOKUP(p3_ssp1_clk, "ssp1", NULL), + + /* PERIPH 5 */ + CLK_LOOKUP(p5_pclk1, "gpio.8", NULL), + CLK_LOOKUP(p5_pclk1, "gpioblock3", NULL), + CLK_LOOKUP(p5_pclk0, "musb-ux500.0", "usb"), + + /* PERIPH 6 */ + CLK_LOOKUP(p6_pclk1, "cryp0", NULL), + CLK_LOOKUP(p6_pclk2, "hash0", NULL), + CLK_LOOKUP(p6_pclk3, "pka", NULL), + CLK_LOOKUP(p6_pclk5, "cfgreg", NULL), + CLK_LOOKUP(p6_mtu0_clk, "mtu0", NULL), + CLK_LOOKUP(p6_mtu1_clk, "mtu1", NULL), + CLK_LOOKUP(p6_pclk4, "hash1", NULL), + CLK_LOOKUP(p6_pclk1, "cryp1", NULL), + CLK_LOOKUP(p6_rng_clk, "rng", NULL), + +}; + +static struct clk_lookup u8500_v2_sysclks[] = { + CLK_LOOKUP(sysclk2, NULL, "sysclk2"), + CLK_LOOKUP(sysclk3, NULL, "sysclk3"), + CLK_LOOKUP(sysclk4, NULL, "sysclk4"), +}; + +static void sysclk_init_disable(struct work_struct *not_used) +{ + int i; + + mutex_lock(&sysclk_mutex); + + /* Enable SWAT */ + if (ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE)) + goto err_swat; + + for (i = 0; i < ARRAY_SIZE(u8500_v2_sysclks); i++) { + struct clk *clk = u8500_v2_sysclks[i].clk; + + /* Disable sysclks */ + if (!clk->enabled && clk->cg_sel) { + if (ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, + (u8)clk->cg_sel)) + goto err_sysclk; + } + } + goto unlock_and_exit; + +err_sysclk: + pr_err("clock: Disable %s failed", u8500_v2_sysclks[i].clk->name); + ab8500_sysctrl_clear(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); + goto unlock_and_exit; + +err_swat: + pr_err("clock: Enable SWAT failed"); + +unlock_and_exit: + mutex_unlock(&sysclk_mutex); +} + +static struct clk *db8500_dbg_clks[] __initdata = { + /* Clock sources */ + &soc0_pll, + &soc1_pll, + &ddr_pll, + &ulp38m4, + &sysclk, + &rtc32k, + /* PRCMU clocks */ + &sgaclk, + &uartclk, + &msp02clk, + &msp1clk, + &i2cclk, + &sdmmcclk, + &slimclk, + &per1clk, + &per2clk, + &per3clk, + &per5clk, + &per6clk, + &per7clk, + &lcdclk, + &bmlclk, + &hsitxclk, + &hsirxclk, + &hdmiclk, + &apeatclk, + &apetraceclk, + &mcdeclk, + &ipi2cclk, + &dsialtclk, + &dsi_pll, + &dsi0clk, + &dsi1clk, + &dsi0escclk, + &dsi1escclk, + &dsi2escclk, + &dmaclk, + &b2r2clk, + &tvclk, + &sspclk, + &rngclk, + &uiccclk, + &sysclk2, + &clkout0, + &clkout1, + &p1_pclk0, + &p1_pclk1, + &p1_pclk2, + &p1_pclk3, + &p1_pclk4, + &p1_pclk5, + &p1_pclk6, + &p1_pclk7, + &p1_pclk8, + &p1_pclk9, + &p1_pclk10, + &p1_pclk11, + &p2_pclk0, + &p2_pclk1, + &p2_pclk2, + &p2_pclk3, + &p2_pclk4, + &p2_pclk5, + &p2_pclk6, + &p2_pclk7, + &p2_pclk8, + &p2_pclk9, + &p2_pclk10, + &p2_pclk11, + &p3_pclk0, + &p3_pclk1, + &p3_pclk2, + &p3_pclk3, + &p3_pclk4, + &p3_pclk5, + &p3_pclk6, + &p3_pclk7, + &p3_pclk8, + &p5_pclk0, + &p5_pclk1, + &p6_pclk0, + &p6_pclk1, + &p6_pclk2, + &p6_pclk3, + &p6_pclk4, + &p6_pclk5, + &p6_pclk6, + &p6_pclk7, +}; + +/* List of clocks which might be enabled from the bootloader */ + +/* + * SOC settings enable bus + kernel clocks of all periphs without + * properly configuring the parents of the kernel clocks for all units. + * Enable and Disable them all to get them into a known and working state. + */ +static struct clk *loader_enabled_clk[] __initdata = { + /* periph 1 */ + &p1_uart0_clk, + &p1_uart1_clk, + &p1_i2c1_clk, + &p1_msp0_clk, + &p1_msp1_clk, + &p1_sdi0_clk, + &p1_i2c2_clk, + &p1_pclk7, /* spi3 */ + &p1_pclk9, /* gpioctrl */ + &p1_i2c4_clk, + + /* periph 2 */ + &p2_i2c3_clk, + &p2_pclk1, /* spi2 */ + &p2_pclk2, /* spi1 */ + /* pwl has an unknown kclk parent, ignore it */ + &p2_sdi4_clk, + &p2_msp2_clk, + &p2_sdi1_clk, + &p2_sdi3_clk, + &p2_pclk8, /* spi0 */ + &p2_ssirx_kclk, /* hsir kernel */ + &p2_ssitx_kclk, /* hsit kernel */ + &p2_pclk9, /* hsir bus */ + &p2_pclk10, /* hsit bus */ + &p2_pclk11, /* gpioctrl */ + /* periph 3 */ + &p3_pclk0, /* fsmc */ + &p3_ssp0_clk, + &p3_ssp1_clk, + &p3_i2c0_clk, + &p3_sdi2_clk, + &p3_ske_clk, + &p3_uart2_clk, + &p3_sdi5_clk, + &p3_pclk8, /* gpio */ + /* periph 5 */ + &p5_pclk0, /* usb */ + &p5_pclk1, /* gpio */ + /* periph 6 */ + /* Leave out rng, cryp0, hash0 and pka */ + &p6_pclk4, /* hash1 */ + &p6_pclk5, /* cr */ + &p6_mtu0_clk, + &p6_mtu1_clk, + /* periph 7 */ + &per7clk, /* PERIPH7 */ + + &bmlclk, /* BML */ + &dsialtclk, /* dsialt */ + &hsirxclk, /* hsirx */ + &hsitxclk, /* hsitx */ + &ipi2cclk, /* ipi2 */ + &lcdclk, /* mcde */ + &b2r2clk, /* b2r2_bus */ +}; + +static int __init init_clock_states(void) +{ + unsigned int i; + /* + * Disable peripheral clocks enabled by bootloader/default + * but without drivers + */ + for (i = 0; i < ARRAY_SIZE(loader_enabled_clk); i++) + if (!clk_enable(loader_enabled_clk[i])) + clk_disable(loader_enabled_clk[i]); + + /* + * APEATCLK and APETRACECLK are enabled at boot and needed + * in order to debug with Lauterbach + */ + if (!clk_enable(&apeatclk)) { + if (!ux500_jtag_enabled()) + clk_disable(&apeatclk); + } + if (!clk_enable(&apetraceclk)) { + if (!ux500_jtag_enabled()) + clk_disable(&apetraceclk); + } + + INIT_DELAYED_WORK(&sysclk_disable_work, sysclk_init_disable); + schedule_delayed_work(&sysclk_disable_work, 10 * HZ); + + return 0; +} +late_initcall(init_clock_states); + +static void __init configure_c2_clocks(void) +{ + sgaclk.parent = &soc0_pll; + sgaclk.mutex = &soc0_pll_mutex; +} + +int __init db8500_clk_init(void) +{ + struct prcmu_fw_version *fw_version; + + /* + * Disable pwl's and slimbus' bus and kernel clocks without touching + * any parents. Because for slimbus, the prcmu fw has not correctly + * configured the clocks at boot and for pwl the kclk parent + * is unknown. + */ + + /* slimbus' bus and kernel clocks */ + writel(1 << 8, __io_address(U8500_CLKRST1_BASE) + PRCC_PCKDIS); + writel(1 << 8, __io_address(U8500_CLKRST1_BASE) + PRCC_KCKDIS); + /* pwl's bus and kernel clocks */ + writel(1 << 3, __io_address(U8500_CLKRST2_BASE) + PRCC_PCKDIS); + writel(1 << 1, __io_address(U8500_CLKRST2_BASE) + PRCC_KCKDIS); + + fw_version = prcmu_get_fw_version(); + if (fw_version != NULL) + switch (fw_version->project) { + case PRCMU_FW_PROJECT_U8500_C2: + case PRCMU_FW_PROJECT_U9500_C2: + case PRCMU_FW_PROJECT_U8520: + configure_c2_clocks(); + break; + default: + break; + } + clkdev_add_table(u8500_v2_sysclks, + ARRAY_SIZE(u8500_v2_sysclks)); + clkdev_add_table(u8500_clocks, + ARRAY_SIZE(u8500_clocks)); +#ifdef CONFIG_DEBUG_FS + clk_debugfs_add_table(u8500_v2_sysclks, ARRAY_SIZE(u8500_v2_sysclks)); + clk_debugfs_add_table(u8500_clocks, ARRAY_SIZE(u8500_clocks)); +#endif + return 0; +} + +int __init db8500_clk_debug_init(void) +{ + return dbx500_clk_debug_init(db8500_dbg_clks, + ARRAY_SIZE(db8500_dbg_clks)); +} diff --git a/arch/arm/mach-ux500/clock-debug.c b/arch/arm/mach-ux500/clock-debug.c new file mode 100644 index 00000000000..1ebc69fe061 --- /dev/null +++ b/arch/arm/mach-ux500/clock-debug.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License terms: GNU General Public License (GPL) version 2 + * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST-Ericsson + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/uaccess.h> +#include <linux/clk.h> +#include <mach/hardware.h> + +#include "clock.h" + +struct clk_debug_info { + struct clk *clk; + struct dentry *dir; + struct dentry *enable; + struct dentry *requests; + int enabled; +}; + +#ifdef CONFIG_DEBUG_FS + +static struct dentry *clk_dir; +static struct dentry *clk_show; +static struct dentry *clk_show_enabled_only; + +static struct clk_debug_info *cdi; +static int num_clks; + +static int clk_show_print(struct seq_file *s, void *p) +{ + int i; + int enabled_only = (int)s->private; + + seq_printf(s, "\n%-20s %10s %s\n", "name", "rate", + "enabled (kernel + debug)"); + for (i = 0; i < num_clks; i++) { + if (enabled_only && !cdi[i].clk->enabled) + continue; + seq_printf(s, + "%-20s %10lu %5d + %d\n", + cdi[i].clk->name, + clk_get_rate(cdi[i].clk), + cdi[i].clk->enabled - cdi[i].enabled, + cdi[i].enabled); + } + + return 0; +} + +static int clk_show_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_show_print, inode->i_private); +} + +static int clk_enable_print(struct seq_file *s, void *p) +{ + struct clk_debug_info *cdi = s->private; + + return seq_printf(s, "%d\n", cdi->enabled); +} + +static int clk_enable_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_enable_print, inode->i_private); +} + +static ssize_t clk_enable_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct clk_debug_info *cdi; + long user_val; + int err; + + cdi = ((struct seq_file *)(file->private_data))->private; + + err = kstrtol_from_user(user_buf, count, 0, &user_val); + + if (err) + return err; + + if ((user_val > 0) && (!cdi->enabled)) { + err = clk_enable(cdi->clk); + if (err) { + pr_err("clock: clk_enable(%s) failed.\n", + cdi->clk->name); + return -EFAULT; + } + cdi->enabled = 1; + } else if ((user_val <= 0) && (cdi->enabled)) { + clk_disable(cdi->clk); + cdi->enabled = 0; + } + return count; +} + +static int clk_requests_print(struct seq_file *s, void *p) +{ + struct clk_debug_info *cdi = s->private; + + return seq_printf(s, "%d\n", cdi->clk->enabled); +} + +static int clk_requests_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_requests_print, inode->i_private); +} + +static const struct file_operations clk_enable_fops = { + .open = clk_enable_open, + .write = clk_enable_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations clk_requests_fops = { + .open = clk_requests_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations clk_show_fops = { + .open = clk_show_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int create_clk_dirs(struct clk_debug_info *cdi, int size) +{ + int i; + + for (i = 0; i < size; i++) { + cdi[i].dir = debugfs_create_dir(cdi[i].clk->name, clk_dir); + if (!cdi[i].dir) + goto no_dir; + } + + for (i = 0; i < size; i++) { + cdi[i].enable = debugfs_create_file("enable", + (S_IRUGO | S_IWUGO), + cdi[i].dir, &cdi[i], + &clk_enable_fops); + if (!cdi[i].enable) + goto no_enable; + } + for (i = 0; i < size; i++) { + cdi[i].requests = debugfs_create_file("requests", S_IRUGO, + cdi[i].dir, &cdi[i], + &clk_requests_fops); + if (!cdi[i].requests) + goto no_requests; + } + return 0; + +no_requests: + while (i--) + debugfs_remove(cdi[i].requests); + i = size; +no_enable: + while (i--) + debugfs_remove(cdi[i].enable); + i = size; +no_dir: + while (i--) + debugfs_remove(cdi[i].dir); + + return -ENOMEM; +} + +int __init dbx500_clk_debug_init(struct clk **clks, int num) +{ + int i; + + cdi = kcalloc(sizeof(struct clk_debug_info), num, GFP_KERNEL); + if (!cdi) + return -ENOMEM; + + for (i = 0; i < num; i++) + cdi[i].clk = clks[i]; + + num_clks = num; + + clk_dir = debugfs_create_dir("clk", NULL); + if (!clk_dir) + goto no_dir; + + clk_show = debugfs_create_file("show", S_IRUGO, clk_dir, (void *)0, + &clk_show_fops); + if (!clk_show) + goto no_show; + + clk_show_enabled_only = debugfs_create_file("show-enabled-only", + S_IRUGO, clk_dir, (void *)1, + &clk_show_fops); + if (!clk_show_enabled_only) + goto no_enabled_only; + + if (create_clk_dirs(cdi, num)) + goto no_clks; + + return 0; + +no_clks: + debugfs_remove(clk_show_enabled_only); +no_enabled_only: + debugfs_remove(clk_show); +no_show: + debugfs_remove(clk_dir); +no_dir: + kfree(cdi); + return -ENOMEM; +} + +static int __init clk_debug_init(void) +{ + if (cpu_is_u8500()) + db8500_clk_debug_init(); + else if (cpu_is_u5500()) + db5500_clk_debug_init(); + + return 0; +} +module_init(clk_debug_init); + +#endif /* CONFIG_DEBUG_FS */ diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index ec35f0aa566..b8bac2d6966 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -7,18 +7,11 @@ * published by the Free Software Foundation. */ #include <linux/module.h> -#include <linux/kernel.h> -#include <linux/list.h> #include <linux/errno.h> -#include <linux/err.h> -#include <linux/clk.h> #include <linux/io.h> -#include <linux/clkdev.h> -#include <linux/cpufreq.h> - -#include <plat/mtu.h> -#include <mach/hardware.h> -#include "clock.h" +#include <linux/spinlock.h> +#include <linux/mfd/abx500/ab8500-sysctrl.h> +#include <linux/mfd/dbx500-prcmu.h> #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -26,477 +19,495 @@ static LIST_HEAD(clk_list); #endif -#define PRCC_PCKEN 0x00 -#define PRCC_PCKDIS 0x04 -#define PRCC_KCKEN 0x08 -#define PRCC_KCKDIS 0x0C - -#define PRCM_YYCLKEN0_MGT_SET 0x510 -#define PRCM_YYCLKEN1_MGT_SET 0x514 -#define PRCM_YYCLKEN0_MGT_CLR 0x518 -#define PRCM_YYCLKEN1_MGT_CLR 0x51C -#define PRCM_YYCLKEN0_MGT_VAL 0x520 -#define PRCM_YYCLKEN1_MGT_VAL 0x524 - -#define PRCM_SVAMMDSPCLK_MGT 0x008 -#define PRCM_SIAMMDSPCLK_MGT 0x00C -#define PRCM_SGACLK_MGT 0x014 -#define PRCM_UARTCLK_MGT 0x018 -#define PRCM_MSP02CLK_MGT 0x01C -#define PRCM_MSP1CLK_MGT 0x288 -#define PRCM_I2CCLK_MGT 0x020 -#define PRCM_SDMMCCLK_MGT 0x024 -#define PRCM_SLIMCLK_MGT 0x028 -#define PRCM_PER1CLK_MGT 0x02C -#define PRCM_PER2CLK_MGT 0x030 -#define PRCM_PER3CLK_MGT 0x034 -#define PRCM_PER5CLK_MGT 0x038 -#define PRCM_PER6CLK_MGT 0x03C -#define PRCM_PER7CLK_MGT 0x040 -#define PRCM_LCDCLK_MGT 0x044 -#define PRCM_BMLCLK_MGT 0x04C -#define PRCM_HSITXCLK_MGT 0x050 -#define PRCM_HSIRXCLK_MGT 0x054 -#define PRCM_HDMICLK_MGT 0x058 -#define PRCM_APEATCLK_MGT 0x05C -#define PRCM_APETRACECLK_MGT 0x060 -#define PRCM_MCDECLK_MGT 0x064 -#define PRCM_IPI2CCLK_MGT 0x068 -#define PRCM_DSIALTCLK_MGT 0x06C -#define PRCM_DMACLK_MGT 0x074 -#define PRCM_B2R2CLK_MGT 0x078 -#define PRCM_TVCLK_MGT 0x07C -#define PRCM_TCR 0x1C8 -#define PRCM_TCR_STOPPED (1 << 16) -#define PRCM_TCR_DOZE_MODE (1 << 17) -#define PRCM_UNIPROCLK_MGT 0x278 -#define PRCM_SSPCLK_MGT 0x280 -#define PRCM_RNGCLK_MGT 0x284 -#define PRCM_UICCCLK_MGT 0x27C - -#define PRCM_MGT_ENABLE (1 << 8) - -static DEFINE_SPINLOCK(clocks_lock); - -static void __clk_enable(struct clk *clk) -{ - if (clk->enabled++ == 0) { - if (clk->parent_cluster) - __clk_enable(clk->parent_cluster); - - if (clk->parent_periph) - __clk_enable(clk->parent_periph); - - if (clk->ops && clk->ops->enable) - clk->ops->enable(clk); +#include "clock.h" +#include "prcc.h" + +DEFINE_MUTEX(clk_opp100_mutex); +static DEFINE_SPINLOCK(clk_spin_lock); +#define NO_LOCK &clk_spin_lock + +static void __iomem *prcmu_base; + +static void __clk_lock(struct clk *clk, void *last_lock, unsigned long *flags) +{ + if (clk->mutex != last_lock) { + if (clk->mutex == NULL) + spin_lock_irqsave(&clk_spin_lock, *flags); + else + mutex_lock(clk->mutex); } } -int clk_enable(struct clk *clk) +static void __clk_unlock(struct clk *clk, void *last_lock, unsigned long flags) +{ + if (clk->mutex != last_lock) { + if (clk->mutex == NULL) + spin_unlock_irqrestore(&clk_spin_lock, flags); + else + mutex_unlock(clk->mutex); + } +} + +void __clk_disable(struct clk *clk, void *current_lock) { unsigned long flags; - spin_lock_irqsave(&clocks_lock, flags); - __clk_enable(clk); - spin_unlock_irqrestore(&clocks_lock, flags); + if (clk == NULL) + return; - return 0; + __clk_lock(clk, current_lock, &flags); + + if (clk->enabled && (--clk->enabled == 0)) { + if ((clk->ops != NULL) && (clk->ops->disable != NULL)) + clk->ops->disable(clk); + __clk_disable(clk->parent, clk->mutex); + __clk_disable(clk->bus_parent, clk->mutex); + } + + __clk_unlock(clk, current_lock, flags); + + return; } -EXPORT_SYMBOL(clk_enable); -static void __clk_disable(struct clk *clk) +int __clk_enable(struct clk *clk, void *current_lock) { - if (--clk->enabled == 0) { - if (clk->ops && clk->ops->disable) - clk->ops->disable(clk); + int err; + unsigned long flags; - if (clk->parent_periph) - __clk_disable(clk->parent_periph); + if (clk == NULL) + return 0; - if (clk->parent_cluster) - __clk_disable(clk->parent_cluster); + __clk_lock(clk, current_lock, &flags); + + if (!clk->enabled) { + err = __clk_enable(clk->bus_parent, clk->mutex); + if (unlikely(err)) + goto bus_parent_error; + + err = __clk_enable(clk->parent, clk->mutex); + if (unlikely(err)) + goto parent_error; + + if ((clk->ops != NULL) && (clk->ops->enable != NULL)) { + err = clk->ops->enable(clk); + if (unlikely(err)) + goto enable_error; + } } + clk->enabled++; + + __clk_unlock(clk, current_lock, flags); + + return 0; + +enable_error: + __clk_disable(clk->parent, clk->mutex); +parent_error: + __clk_disable(clk->bus_parent, clk->mutex); +bus_parent_error: + + __clk_unlock(clk, current_lock, flags); + + return err; } -void clk_disable(struct clk *clk) +unsigned long __clk_get_rate(struct clk *clk, void *current_lock) { + unsigned long rate; unsigned long flags; - WARN_ON(!clk->enabled); + if (clk == NULL) + return 0; + + __clk_lock(clk, current_lock, &flags); - spin_lock_irqsave(&clocks_lock, flags); - __clk_disable(clk); - spin_unlock_irqrestore(&clocks_lock, flags); + if ((clk->ops != NULL) && (clk->ops->get_rate != NULL)) + rate = clk->ops->get_rate(clk); + else if (clk->rate) + rate = clk->rate; + else + rate = __clk_get_rate(clk->parent, clk->mutex); + + __clk_unlock(clk, current_lock, flags); + + return rate; } -EXPORT_SYMBOL(clk_disable); -/* - * The MTU has a separate, rather complex muxing setup - * with alternative parents (peripheral cluster or - * ULP or fixed 32768 Hz) depending on settings - */ -static unsigned long clk_mtu_get_rate(struct clk *clk) +static long __clk_round_rate(struct clk *clk, unsigned long rate) { - void __iomem *addr; - u32 tcr; - int mtu = (int) clk->data; - /* - * One of these is selected eventually - * TODO: Replace the constant with a reference - * to the ULP source once this is modeled. - */ - unsigned long clk32k = 32768; - unsigned long mturate; - unsigned long retclk; - - if (cpu_is_u5500()) - addr = __io_address(U5500_PRCMU_BASE); - else if (cpu_is_u8500()) - addr = __io_address(U8500_PRCMU_BASE); - else - ux500_unknown_soc(); + if ((clk->ops != NULL) && (clk->ops->round_rate != NULL)) + return clk->ops->round_rate(clk, rate); - /* - * On a startup, always conifgure the TCR to the doze mode; - * bootloaders do it for us. Do this in the kernel too. - */ - writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR); + return -ENOSYS; +} - tcr = readl(addr + PRCM_TCR); +static int __clk_set_rate(struct clk *clk, unsigned long rate) +{ + if ((clk->ops != NULL) && (clk->ops->set_rate != NULL)) + return clk->ops->set_rate(clk, rate); - /* Get the rate from the parent as a default */ - if (clk->parent_periph) - mturate = clk_get_rate(clk->parent_periph); - else if (clk->parent_cluster) - mturate = clk_get_rate(clk->parent_cluster); - else - /* We need to be connected SOMEWHERE */ - BUG(); + return -ENOSYS; +} - /* Return the clock selected for this MTU */ - if (tcr & (1 << mtu)) - retclk = clk32k; - else - retclk = mturate; +int clk_enable(struct clk *clk) +{ + if (clk == NULL) + return -EINVAL; - pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk); - return retclk; + return __clk_enable(clk, NO_LOCK); } +EXPORT_SYMBOL(clk_enable); -unsigned long clk_get_rate(struct clk *clk) +void clk_disable(struct clk *clk) { - unsigned long rate; - /* - * If there is a custom getrate callback for this clock, - * it will take precedence. - */ - if (clk->get_rate) - return clk->get_rate(clk); - - if (clk->ops && clk->ops->get_rate) - return clk->ops->get_rate(clk); - - rate = clk->rate; - if (!rate) { - if (clk->parent_periph) - rate = clk_get_rate(clk->parent_periph); - else if (clk->parent_cluster) - rate = clk_get_rate(clk->parent_cluster); - } + if (clk == NULL) + return; - return rate; + WARN_ON(!clk->enabled); + __clk_disable(clk, NO_LOCK); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk == NULL) + return 0; + + return __clk_get_rate(clk, NO_LOCK); } EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { - /*TODO*/ - return rate; + long rounded_rate; + unsigned long flags; + + if (clk == NULL) + return -EINVAL; + + __clk_lock(clk, NO_LOCK, &flags); + + rounded_rate = __clk_round_rate(clk, rate); + + __clk_unlock(clk, NO_LOCK, flags); + + return rounded_rate; } EXPORT_SYMBOL(clk_round_rate); +long clk_round_rate_rec(struct clk *clk, unsigned long rate) +{ + long rounded_rate; + unsigned long flags; + + if ((clk == NULL) || (clk->parent == NULL)) + return -EINVAL; + + __clk_lock(clk->parent, clk->mutex, &flags); + + rounded_rate = __clk_round_rate(clk->parent, rate); + + __clk_unlock(clk->parent, clk->mutex, flags); + + return rounded_rate; +} + +static void lock_parent_rate(struct clk *clk) +{ + unsigned long flags; + + if (clk->parent == NULL) + return; + + __clk_lock(clk->parent, clk->mutex, &flags); + + lock_parent_rate(clk->parent); + clk->parent->rate_locked++; + + __clk_unlock(clk->parent, clk->mutex, flags); +} + +static void unlock_parent_rate(struct clk *clk) +{ + unsigned long flags; + + if (clk->parent == NULL) + return; + + __clk_lock(clk->parent, clk->mutex, &flags); + + unlock_parent_rate(clk->parent); + clk->parent->rate_locked--; + + __clk_unlock(clk->parent, clk->mutex, flags); +} + int clk_set_rate(struct clk *clk, unsigned long rate) { - clk->rate = rate; - return 0; + int err; + unsigned long flags; + + if (clk == NULL) + return -EINVAL; + + __clk_lock(clk, NO_LOCK, &flags); + + if (clk->enabled) { + err = -EBUSY; + goto unlock_and_return; + } + if (clk->rate_locked) { + err = -EAGAIN; + goto unlock_and_return; + } + + lock_parent_rate(clk); + err = __clk_set_rate(clk, rate); + unlock_parent_rate(clk); + +unlock_and_return: + __clk_unlock(clk, NO_LOCK, flags); + + return err; } EXPORT_SYMBOL(clk_set_rate); +int clk_set_rate_rec(struct clk *clk, unsigned long rate) +{ + int err; + unsigned long flags; + + if ((clk == NULL) || (clk->parent == NULL)) + return -EINVAL; + + __clk_lock(clk->parent, clk->mutex, &flags); + + if (clk->parent->enabled) { + err = -EBUSY; + goto unlock_and_return; + } + if (clk->parent->rate_locked != 1) { + err = -EAGAIN; + goto unlock_and_return; + } + err = __clk_set_rate(clk->parent, rate); + +unlock_and_return: + __clk_unlock(clk->parent, clk->mutex, flags); + + return err; +} + int clk_set_parent(struct clk *clk, struct clk *parent) { - /*TODO*/ - return -ENOSYS; + int err = 0; + unsigned long flags; + struct clk **p; + + if ((clk == NULL) || (clk->parents == NULL)) + return -EINVAL; + for (p = clk->parents; *p != parent; p++) { + if (*p == NULL) /* invalid parent */ + return -EINVAL; + } + + __clk_lock(clk, NO_LOCK, &flags); + + if ((clk->ops != NULL) && (clk->ops->set_parent != NULL)) { + err = clk->ops->set_parent(clk, parent); + if (err) + goto unlock_and_return; + } else if (clk->enabled) { + err = __clk_enable(parent, clk->mutex); + if (err) + goto unlock_and_return; + __clk_disable(clk->parent, clk->mutex); + } + + clk->parent = parent; + +unlock_and_return: + __clk_unlock(clk, NO_LOCK, flags); + + return err; } -EXPORT_SYMBOL(clk_set_parent); -static void clk_prcmu_enable(struct clk *clk) +/* PRCMU clock operations. */ + +static int prcmu_clk_enable(struct clk *clk) { - void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE) - + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off; + return prcmu_request_clock(clk->cg_sel, true); +} + +static void prcmu_clk_disable(struct clk *clk) +{ + if (prcmu_request_clock(clk->cg_sel, false)) { + pr_err("clock: %s failed to disable %s.\n", __func__, + clk->name); + } +} + +static int request_ape_opp100(bool enable) +{ + static unsigned int requests; + + if (enable) { + if (0 == requests++) { + return prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, + "clock", 100); + } + } else if (1 == requests--) { + prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "clock"); + } + return 0; +} + +static int prcmu_opp100_clk_enable(struct clk *clk) +{ + int r; - writel(1 << clk->prcmu_cg_bit, cg_set_reg); + r = request_ape_opp100(true); + if (r) { + pr_err("clock: %s failed to request APE OPP 100%% for %s.\n", + __func__, clk->name); + return r; + } + return prcmu_request_clock(clk->cg_sel, true); +} + +static void prcmu_opp100_clk_disable(struct clk *clk) +{ + if (prcmu_request_clock(clk->cg_sel, false)) + goto out_error; + if (request_ape_opp100(false)) + goto out_error; + return; + +out_error: + pr_err("clock: %s failed to disable %s.\n", __func__, clk->name); +} + +static unsigned long prcmu_clk_get_rate(struct clk *clk) +{ + return prcmu_clock_rate(clk->cg_sel); } -static void clk_prcmu_disable(struct clk *clk) +static long prcmu_clk_round_rate(struct clk *clk, unsigned long rate) { - void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE) - + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off; + return prcmu_round_clock_rate(clk->cg_sel, rate); +} - writel(1 << clk->prcmu_cg_bit, cg_clr_reg); +static int prcmu_clk_set_rate(struct clk *clk, unsigned long rate) +{ + return prcmu_set_clock_rate(clk->cg_sel, rate); } -static struct clkops clk_prcmu_ops = { - .enable = clk_prcmu_enable, - .disable = clk_prcmu_disable, +struct clkops prcmu_clk_ops = { + .enable = prcmu_clk_enable, + .disable = prcmu_clk_disable, + .get_rate = prcmu_clk_get_rate, +}; + +struct clkops prcmu_scalable_clk_ops = { + .enable = prcmu_clk_enable, + .disable = prcmu_clk_disable, + .get_rate = prcmu_clk_get_rate, + .round_rate = prcmu_clk_round_rate, + .set_rate = prcmu_clk_set_rate, }; -static unsigned int clkrst_base[] = { - [1] = U8500_CLKRST1_BASE, - [2] = U8500_CLKRST2_BASE, - [3] = U8500_CLKRST3_BASE, - [5] = U8500_CLKRST5_BASE, - [6] = U8500_CLKRST6_BASE, +struct clkops prcmu_opp100_clk_ops = { + .enable = prcmu_opp100_clk_enable, + .disable = prcmu_opp100_clk_disable, + .get_rate = prcmu_clk_get_rate, }; -static void clk_prcc_enable(struct clk *clk) +/* PRCC clock operations. */ + +static int prcc_pclk_enable(struct clk *clk) { - void __iomem *addr = __io_address(clkrst_base[clk->cluster]); + void __iomem *io_base = __io_address(clk->io_base); + + writel(clk->cg_sel, (io_base + PRCC_PCKEN)); + while (!(readl(io_base + PRCC_PCKSR) & clk->cg_sel)) + cpu_relax(); + return 0; +} - if (clk->prcc_kernel != -1) - writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN); +static void prcc_pclk_disable(struct clk *clk) +{ + void __iomem *io_base = __io_address(clk->io_base); - if (clk->prcc_bus != -1) - writel(1 << clk->prcc_bus, addr + PRCC_PCKEN); + writel(clk->cg_sel, (io_base + PRCC_PCKDIS)); } -static void clk_prcc_disable(struct clk *clk) +struct clkops prcc_pclk_ops = { + .enable = prcc_pclk_enable, + .disable = prcc_pclk_disable, +}; + +static int prcc_kclk_enable(struct clk *clk) { - void __iomem *addr = __io_address(clkrst_base[clk->cluster]); + int err; + void __iomem *io_base = __io_address(clk->io_base); + + err = __clk_enable(clk->clock, clk->mutex); + if (err) + return err; - if (clk->prcc_bus != -1) - writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS); + writel(clk->cg_sel, (io_base + PRCC_KCKEN)); + while (!(readl(io_base + PRCC_KCKSR) & clk->cg_sel)) + cpu_relax(); - if (clk->prcc_kernel != -1) - writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS); + __clk_disable(clk->clock, clk->mutex); + + return 0; } -static struct clkops clk_prcc_ops = { - .enable = clk_prcc_enable, - .disable = clk_prcc_disable, +static void prcc_kclk_disable(struct clk *clk) +{ + void __iomem *io_base = __io_address(clk->io_base); + + (void)__clk_enable(clk->clock, clk->mutex); + writel(clk->cg_sel, (io_base + PRCC_KCKDIS)); + __clk_disable(clk->clock, clk->mutex); +} + +struct clkops prcc_kclk_ops = { + .enable = prcc_kclk_enable, + .disable = prcc_kclk_disable, }; -static struct clk clk_32khz = { - .name = "clk_32khz", - .rate = 32000, +struct clkops prcc_kclk_rec_ops = { + .enable = prcc_kclk_enable, + .disable = prcc_kclk_disable, + .round_rate = clk_round_rate_rec, + .set_rate = clk_set_rate_rec, }; -/* - * PRCMU level clock gating - */ +#ifdef CONFIG_CPU_FREQ +extern unsigned long dbx500_cpufreq_getfreq(void); -/* Bank 0 */ -static DEFINE_PRCMU_CLK(svaclk, 0x0, 2, SVAMMDSPCLK); -static DEFINE_PRCMU_CLK(siaclk, 0x0, 3, SIAMMDSPCLK); -static DEFINE_PRCMU_CLK(sgaclk, 0x0, 4, SGACLK); -static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000); -static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK); -static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */ -static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000); -static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000); -static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK); -static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK); -static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK); -static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK); -static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK); -static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000); -static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK); -static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK); -static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK); -static DEFINE_PRCMU_CLK(hsirxclk, 0x0, 20, HSIRXCLK); -static DEFINE_PRCMU_CLK(hdmiclk, 0x0, 21, HDMICLK); -static DEFINE_PRCMU_CLK(apeatclk, 0x0, 22, APEATCLK); -static DEFINE_PRCMU_CLK(apetraceclk, 0x0, 23, APETRACECLK); -static DEFINE_PRCMU_CLK(mcdeclk, 0x0, 24, MCDECLK); -static DEFINE_PRCMU_CLK(ipi2clk, 0x0, 25, IPI2CCLK); -static DEFINE_PRCMU_CLK(dsialtclk, 0x0, 26, DSIALTCLK); /* v1 */ -static DEFINE_PRCMU_CLK(dmaclk, 0x0, 27, DMACLK); -static DEFINE_PRCMU_CLK(b2r2clk, 0x0, 28, B2R2CLK); -static DEFINE_PRCMU_CLK(tvclk, 0x0, 29, TVCLK); -static DEFINE_PRCMU_CLK(uniproclk, 0x0, 30, UNIPROCLK); /* v1 */ -static DEFINE_PRCMU_CLK_RATE(sspclk, 0x0, 31, SSPCLK, 48000000); /* v1 */ - -/* Bank 1 */ -static DEFINE_PRCMU_CLK(rngclk, 0x4, 0, RNGCLK); /* v1 */ -static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */ +unsigned long clk_smp_twd_get_rate(struct clk *clk) +{ + return dbx500_cpufreq_getfreq() / 2; +} -/* - * PRCC level clock gating - * Format: per#, clk, PCKEN bit, KCKEN bit, parent - */ +static struct clkops clk_smp_twd_ops = { + .get_rate = clk_smp_twd_get_rate, +}; -/* Peripheral Cluster #1 */ -static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); -static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); -static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); -static DEFINE_PRCC_CLK(1, spi3, 7, -1, NULL); -static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); -static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); -static DEFINE_PRCC_CLK(1, msp1, 4, 4, &clk_msp1clk); -static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); -static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); -static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); -static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); - -/* Peripheral Cluster #2 */ -static DEFINE_PRCC_CLK(2, gpio1, 11, -1, NULL); -static DEFINE_PRCC_CLK(2, ssitx, 10, 7, NULL); -static DEFINE_PRCC_CLK(2, ssirx, 9, 6, NULL); -static DEFINE_PRCC_CLK(2, spi0, 8, -1, NULL); -static DEFINE_PRCC_CLK(2, sdi3, 7, 5, &clk_sdmmcclk); -static DEFINE_PRCC_CLK(2, sdi1, 6, 4, &clk_sdmmcclk); -static DEFINE_PRCC_CLK(2, msp2, 5, 3, &clk_msp02clk); -static DEFINE_PRCC_CLK(2, sdi4, 4, 2, &clk_sdmmcclk); -static DEFINE_PRCC_CLK(2, pwl, 3, 1, NULL); -static DEFINE_PRCC_CLK(2, spi1, 2, -1, NULL); -static DEFINE_PRCC_CLK(2, spi2, 1, -1, NULL); -static DEFINE_PRCC_CLK(2, i2c3, 0, 0, &clk_i2cclk); - -/* Peripheral Cluster #3 */ -static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); -static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); -static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); -static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); -static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); -static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); -static DEFINE_PRCC_CLK(3, ssp1, 2, 2, &clk_sspclk); -static DEFINE_PRCC_CLK(3, ssp0, 1, 1, &clk_sspclk); -static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); - -/* Peripheral Cluster #4 is in the always on domain */ - -/* Peripheral Cluster #5 */ -static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); -static DEFINE_PRCC_CLK(5, usb, 0, 0, NULL); - -/* Peripheral Cluster #6 */ - -/* MTU ID in data */ -static DEFINE_PRCC_CLK_CUSTOM(6, mtu1, 8, -1, NULL, clk_mtu_get_rate, 1); -static DEFINE_PRCC_CLK_CUSTOM(6, mtu0, 7, -1, NULL, clk_mtu_get_rate, 0); -static DEFINE_PRCC_CLK(6, cfgreg, 6, 6, NULL); -static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); -static DEFINE_PRCC_CLK(6, unipro, 4, 1, &clk_uniproclk); -static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); -static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); -static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); -static DEFINE_PRCC_CLK(6, rng, 0, 0, &clk_rngclk); - -static struct clk clk_dummy_apb_pclk = { - .name = "apb_pclk", +static struct clk clk_smp_twd = { + .name = "smp_twd", + .ops = &clk_smp_twd_ops, }; -static struct clk_lookup u8500_clks[] = { - CLK(dummy_apb_pclk, NULL, "apb_pclk"), - - /* Peripheral Cluster #1 */ - CLK(gpio0, "gpio.0", NULL), - CLK(gpio0, "gpio.1", NULL), - CLK(slimbus0, "slimbus0", NULL), - CLK(i2c2, "nmk-i2c.2", NULL), - CLK(sdi0, "sdi0", NULL), - CLK(msp0, "msp0", NULL), - CLK(i2c1, "nmk-i2c.1", NULL), - CLK(uart1, "uart1", NULL), - CLK(uart0, "uart0", NULL), - - /* Peripheral Cluster #3 */ - CLK(gpio2, "gpio.2", NULL), - CLK(gpio2, "gpio.3", NULL), - CLK(gpio2, "gpio.4", NULL), - CLK(gpio2, "gpio.5", NULL), - CLK(sdi5, "sdi5", NULL), - CLK(uart2, "uart2", NULL), - CLK(ske, "ske", NULL), - CLK(ske, "nmk-ske-keypad", NULL), - CLK(sdi2, "sdi2", NULL), - CLK(i2c0, "nmk-i2c.0", NULL), - CLK(fsmc, "fsmc", NULL), - - /* Peripheral Cluster #5 */ - CLK(gpio3, "gpio.8", NULL), - - /* Peripheral Cluster #6 */ - CLK(hash1, "hash1", NULL), - CLK(pka, "pka", NULL), - CLK(hash0, "hash0", NULL), - CLK(cryp0, "cryp0", NULL), - - /* PRCMU level clock gating */ - - /* Bank 0 */ - CLK(svaclk, "sva", NULL), - CLK(siaclk, "sia", NULL), - CLK(sgaclk, "sga", NULL), - CLK(slimclk, "slim", NULL), - CLK(lcdclk, "lcd", NULL), - CLK(bmlclk, "bml", NULL), - CLK(hsitxclk, "stm-hsi.0", NULL), - CLK(hsirxclk, "stm-hsi.1", NULL), - CLK(hdmiclk, "hdmi", NULL), - CLK(apeatclk, "apeat", NULL), - CLK(apetraceclk, "apetrace", NULL), - CLK(mcdeclk, "mcde", NULL), - CLK(ipi2clk, "ipi2", NULL), - CLK(dmaclk, "dma40.0", NULL), - CLK(b2r2clk, "b2r2", NULL), - CLK(tvclk, "tv", NULL), - - /* Peripheral Cluster #1 */ - CLK(i2c4, "nmk-i2c.4", NULL), - CLK(spi3, "spi3", NULL), - CLK(msp1, "msp1", NULL), - - /* Peripheral Cluster #2 */ - CLK(gpio1, "gpio.6", NULL), - CLK(gpio1, "gpio.7", NULL), - CLK(ssitx, "ssitx", NULL), - CLK(ssirx, "ssirx", NULL), - CLK(spi0, "spi0", NULL), - CLK(sdi3, "sdi3", NULL), - CLK(sdi1, "sdi1", NULL), - CLK(msp2, "msp2", NULL), - CLK(sdi4, "sdi4", NULL), - CLK(pwl, "pwl", NULL), - CLK(spi1, "spi1", NULL), - CLK(spi2, "spi2", NULL), - CLK(i2c3, "nmk-i2c.3", NULL), - - /* Peripheral Cluster #3 */ - CLK(ssp1, "ssp1", NULL), - CLK(ssp0, "ssp0", NULL), - - /* Peripheral Cluster #5 */ - CLK(usb, "musb-ux500.0", "usb"), - - /* Peripheral Cluster #6 */ - CLK(mtu1, "mtu1", NULL), - CLK(mtu0, "mtu0", NULL), - CLK(cfgreg, "cfgreg", NULL), - CLK(hash1, "hash1", NULL), - CLK(unipro, "unipro", NULL), - CLK(rng, "rng", NULL), - - /* PRCMU level clock gating */ - - /* Bank 0 */ - CLK(uniproclk, "uniproclk", NULL), - CLK(dsialtclk, "dsialt", NULL), - - /* Bank 1 */ - CLK(rngclk, "rng", NULL), - CLK(uiccclk, "uicc", NULL), +static struct clk_lookup clk_smp_twd_lookup = { + .clk = &clk_smp_twd, + .dev_id = "smp_twd", }; +#endif #ifdef CONFIG_DEBUG_FS /* @@ -585,8 +596,8 @@ err_out: static int clk_debugfs_register_one(struct clk *c) { - struct clk *pa = c->parent_periph; - struct clk *bpa = c->parent_cluster; + struct clk *pa = c->parent; + struct clk *bpa = c->bus_parent; if (!(bpa && !pa)) { c->dent = clk_debugfs_register_dir(c, @@ -610,8 +621,8 @@ static int clk_debugfs_register_one(struct clk *c) static int clk_debugfs_register(struct clk *c) { int err; - struct clk *pa = c->parent_periph; - struct clk *bpa = c->parent_cluster; + struct clk *pa = c->parent; + struct clk *bpa = c->bus_parent; if (pa && (!pa->dent && !pa->dent_bus)) { err = clk_debugfs_register(pa); @@ -658,66 +669,25 @@ err_out: late_initcall(clk_debugfs_init); #endif /* defined(CONFIG_DEBUG_FS) */ -unsigned long clk_smp_twd_rate = 500000000; - -unsigned long clk_smp_twd_get_rate(struct clk *clk) -{ - return clk_smp_twd_rate; -} - -static struct clk clk_smp_twd = { - .get_rate = clk_smp_twd_get_rate, - .name = "smp_twd", -}; - -static struct clk_lookup clk_smp_twd_lookup = { - .dev_id = "smp_twd", - .clk = &clk_smp_twd, -}; - -#ifdef CONFIG_CPU_FREQ - -static int clk_twd_cpufreq_transition(struct notifier_block *nb, - unsigned long state, void *data) -{ - struct cpufreq_freqs *f = data; - - if (state == CPUFREQ_PRECHANGE) { - /* Save frequency in simple Hz */ - clk_smp_twd_rate = (f->new * 1000) / 2; - } - - return NOTIFY_OK; -} - -static struct notifier_block clk_twd_cpufreq_nb = { - .notifier_call = clk_twd_cpufreq_transition, -}; - -static int clk_init_smp_twd_cpufreq(void) -{ - return cpufreq_register_notifier(&clk_twd_cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); -} -late_initcall(clk_init_smp_twd_cpufreq); - -#endif - int __init clk_init(void) { - if (cpu_is_u5500()) { - /* Clock tree for U5500 not implemented yet */ - clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; - clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; - clk_uartclk.rate = 36360000; - clk_sdmmcclk.rate = 99900000; + if (cpu_is_u8500()) { + prcmu_base = __io_address(U8500_PRCMU_BASE); + } else if (cpu_is_u5500()) { + prcmu_base = __io_address(U5500_PRCMU_BASE); + } else { + pr_err("clock: Unknown DB Asic.\n"); + return -EIO; } - clkdev_add_table(u8500_clks, ARRAY_SIZE(u8500_clks)); - clkdev_add(&clk_smp_twd_lookup); + if (cpu_is_u8500()) + db8500_clk_init(); + else if (cpu_is_u5500()) + db5500_clk_init(); -#ifdef CONFIG_DEBUG_FS - clk_debugfs_add_table(u8500_clks, ARRAY_SIZE(u8500_clks)); +#ifdef CONFIG_CPU_FREQ + clkdev_add(&clk_smp_twd_lookup); #endif + return 0; } diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h index d776ada08db..2403e51dc7f 100644 --- a/arch/arm/mach-ux500/clock.h +++ b/arch/arm/mach-ux500/clock.h @@ -1,11 +1,61 @@ /* - * Copyright (C) 2010 ST-Ericsson + * Copyright (C) 2010 ST-Ericsson SA * Copyright (C) 2009 STMicroelectronics * * 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 UX500_CLOCK_H +#define UX500_CLOCK_H + +#include <linux/clkdev.h> + +/** + * struct clk + * @ops: The hardware specific operations defined for the clock. + * @name: The name of the clock. + * @mutex: The mutex to lock when operating on the clock. %NULL means that + * the common clock spinlock will be used. + * @enabled: A reference counter of the enable requests for the clock. + * @rate_locked: A rate lock counter used by clk_set_rate(). + * @opp100: A flag saying whether the clock is requested to run at the + * OPP 100%% frequency. + * @rate: The frequency of the clock. For scalable and scaling clocks, + * this is the OPP 100%% frequency. + * @io_base: An IO memory base address, meaningful only when considered + * together with the defined @ops. + * @cg_sel: Clock gate selector, meaningful only when considered together + * with the specified @ops. + * @parent: The current (or only) parent clock of the clock. + * @bus_parent: The (optional) auxiliary bus clock "parent" of the clock. + * @parents: A list of the possible parents the clock can have. This should + * be a %NULL-terminated &struct_clk array. Present if and only + * if clk_set_parent() is implemented for the clock. + * @regulator: The regulator needed to have the clock functional, if any. + * @clock: The clock needed to control the clock, if any. + */ +struct clk { + const struct clkops *ops; + const char *name; + struct mutex *mutex; + unsigned int enabled; + unsigned int rate_locked; + bool opp100; + unsigned long rate; + unsigned int io_base; + u32 cg_sel; + struct clk *parent; + struct clk *bus_parent; + struct clk **parents; + struct regulator *regulator; + struct clk *clock; + struct list_head list; +#if defined(CONFIG_DEBUG_FS) + struct dentry *dent; /* For visible tree hierarchy */ + struct dentry *dent_bus; /* For visible tree hierarchy */ +#endif +}; /** * struct clkops - ux500 clock operations @@ -18,135 +68,120 @@ * NULL, the rate in the struct clk will be used. */ struct clkops { - void (*enable) (struct clk *); - void (*disable) (struct clk *); - unsigned long (*get_rate) (struct clk *); + int (*enable)(struct clk *); + void (*disable)(struct clk *); + unsigned long (*get_rate)(struct clk *); + int (*set_rate)(struct clk *, unsigned long); + long (*round_rate)(struct clk *, unsigned long); int (*set_parent)(struct clk *, struct clk *); }; -/** - * struct clk - ux500 clock structure - * @ops: pointer to clkops struct used to control this clock - * @name: name, for debugging - * @enabled: refcount. positive if enabled, zero if disabled - * @get_rate: custom callback for getting the clock rate - * @data: custom per-clock data for example for the get_rate - * callback - * @rate: fixed rate for clocks which don't implement - * ops->getrate - * @prcmu_cg_off: address offset of the combined enable/disable register - * (used on u8500v1) - * @prcmu_cg_bit: bit in the combined enable/disable register (used on - * u8500v1) - * @prcmu_cg_mgt: address of the enable/disable register (used on - * u8500ed) - * @cluster: peripheral cluster number - * @prcc_bus: bit for the bus clock in the peripheral's CLKRST - * @prcc_kernel: bit for the kernel clock in the peripheral's CLKRST. - * -1 if no kernel clock exists. - * @parent_cluster: pointer to parent's cluster clk struct - * @parent_periph: pointer to parent's peripheral clk struct - * - * Peripherals are organised into clusters, and each cluster has an associated - * bus clock. Some peripherals also have a parent peripheral clock. - * - * In order to enable a clock for a peripheral, we need to enable: - * (1) the parent cluster (bus) clock at the PRCMU level - * (2) the parent peripheral clock (if any) at the PRCMU level - * (3) the peripheral's bus & kernel clock at the PRCC level - * - * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each - * of the cluster and peripheral clocks, and hooking these as the parents of - * the individual peripheral clocks. - * - * (3) is handled by specifying the bits in the PRCC control registers required - * to enable these clocks and modifying them in the ->enable and - * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK). - * - * This structure describes both the PRCMU-level clocks and PRCC-level clocks. - * The prcmu_* fields are only used for the PRCMU clocks, and the cluster, - * prcc, and parent pointers are only used for the PRCC-level clocks. - */ -struct clk { - const struct clkops *ops; - const char *name; - unsigned int enabled; - unsigned long (*get_rate)(struct clk *); - void *data; - - unsigned long rate; - struct list_head list; +extern struct clkops prcmu_clk_ops; +extern struct clkops prcmu_scalable_clk_ops; +extern struct clkops prcmu_opp100_clk_ops; +extern struct mutex clk_opp100_mutex; +extern struct clkops prcc_pclk_ops; +extern struct clkops prcc_kclk_ops; +extern struct clkops prcc_kclk_rec_ops; +extern struct clkops sga_clk_ops; - /* These three are only for PRCMU clks */ +#define CLK_LOOKUP(_clk, _dev_id, _con_id) \ + { .dev_id = _dev_id, .con_id = _con_id, .clk = &_clk } - unsigned int prcmu_cg_off; - unsigned int prcmu_cg_bit; - unsigned int prcmu_cg_mgt; - - /* The rest are only for PRCC clks */ - - int cluster; - unsigned int prcc_bus; - unsigned int prcc_kernel; - - struct clk *parent_cluster; - struct clk *parent_periph; -#if defined(CONFIG_DEBUG_FS) - struct dentry *dent; /* For visible tree hierarchy */ - struct dentry *dent_bus; /* For visible tree hierarchy */ -#endif -}; +/* Define PRCMU Clock */ +#define DEF_PRCMU_CLK(_name, _cg_sel, _rate) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcmu_clk_ops, \ + .cg_sel = _cg_sel, \ + .rate = _rate, \ + } -#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \ -struct clk clk_##_name = { \ - .name = #_name, \ - .ops = &clk_prcmu_ops, \ - .prcmu_cg_off = _cg_off, \ - .prcmu_cg_bit = _cg_bit, \ - .prcmu_cg_mgt = PRCM_##_reg##_MGT \ +#define DEF_PRCMU_SCALABLE_CLK(_name, _cg_sel) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcmu_scalable_clk_ops, \ + .cg_sel = _cg_sel, \ } -#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate) \ -struct clk clk_##_name = { \ - .name = #_name, \ - .ops = &clk_prcmu_ops, \ - .prcmu_cg_off = _cg_off, \ - .prcmu_cg_bit = _cg_bit, \ - .rate = _rate, \ - .prcmu_cg_mgt = PRCM_##_reg##_MGT \ +/* Use this for clocks that are only defined at OPP 100%. */ +#define DEF_PRCMU_OPP100_CLK(_name, _cg_sel, _rate) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcmu_opp100_clk_ops, \ + .cg_sel = _cg_sel, \ + .rate = _rate, \ + .mutex = &clk_opp100_mutex, \ } -#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \ -struct clk clk_##_name = { \ - .name = #_name, \ - .ops = &clk_prcc_ops, \ - .cluster = _pclust, \ - .prcc_bus = _bus_en, \ - .prcc_kernel = _kernel_en, \ - .parent_cluster = &clk_per##_pclust##clk, \ - .parent_periph = _kernclk \ +/* Define PRCC clock */ +#define DEF_PRCC_PCLK(_name, _io_base, _cg_bit, _parent) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcc_pclk_ops, \ + .io_base = _io_base, \ + .cg_sel = BIT(_cg_bit), \ + .parent = _parent, \ } -#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \ -struct clk clk_##_name = { \ - .name = #_name, \ - .ops = &clk_prcc_ops, \ - .cluster = _pclust, \ - .prcc_bus = _bus_en, \ - .prcc_kernel = _kernel_en, \ - .parent_cluster = &clk_per##_pclust##clk, \ - .parent_periph = _kernclk, \ - .get_rate = _callback, \ - .data = (void *) _data \ +#define DEF_PRCC_KCLK(_name, _io_base, _cg_bit, _parent, _clock) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &prcc_kclk_ops, \ + .io_base = _io_base, \ + .cg_sel = BIT(_cg_bit), \ + .parent = _parent, \ + .clock = _clock, \ } +#define DEF_PER_CLK(_name, _bus_parent, _parent) \ + struct clk _name = { \ + .name = #_name, \ + .parent = _parent, \ + .bus_parent = _bus_parent, \ + } -#define CLK(_clk, _devname, _conname) \ - { \ - .clk = &clk_##_clk, \ - .dev_id = _devname, \ - .con_id = _conname, \ +#define DEF_MTU_CLK(_cg_sel, _name, _bus_parent) \ + struct clk _name = { \ + .name = #_name, \ + .ops = &mtu_clk_ops, \ + .cg_sel = _cg_sel, \ + .bus_parent = _bus_parent, \ } -int __init clk_db8500_ed_fixup(void); +/* Functions defined in clock.c */ int __init clk_init(void); +void clks_register(struct clk_lookup *clks, size_t num); +int __clk_enable(struct clk *clk, void *current_lock); +void __clk_disable(struct clk *clk, void *current_lock); +unsigned long __clk_get_rate(struct clk *clk, void *current_lock); +long clk_round_rate_rec(struct clk *clk, unsigned long rate); +int clk_set_rate_rec(struct clk *clk, unsigned long rate); + +#ifdef CONFIG_DEBUG_FS +int dbx500_clk_debug_init(struct clk **clks, int num); +void clk_debugfs_add_table(struct clk_lookup *cl, size_t num); +#else +static inline int dbx500_clk_debug_init(struct clk **clks, int num) +{ + return 0; +} +#endif + +#ifdef CONFIG_UX500_SOC_DB8500 +int __init db8500_clk_init(void); +int __init db8500_clk_debug_init(void); +#else +static inline int db8500_clk_init(void) { return 0; } +static inline int db8500_clk_debug_init(void) { return 0; } +#endif + +#ifdef CONFIG_UX500_SOC_DB5500 +int __init db5500_clk_init(void); +int __init db5500_clk_debug_init(void); +#else +static inline int db5500_clk_init(void) { return 0; } +static inline int db5500_clk_debug_init(void) { return 0; } +#endif + +#endif diff --git a/arch/arm/mach-ux500/cpuidle.c b/arch/arm/mach-ux500/cpuidle.c new file mode 100644 index 00000000000..b54884bd254 --- /dev/null +++ b/arch/arm/mach-ux500/cpuidle.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012 Linaro : Daniel Lezcano <daniel.lezcano@linaro.org> (IBM) + * + * Based on the work of Rickard Andersson <rickard.andersson@stericsson.com> + * and Jonas Aaberg <jonas.aberg@stericsson.com>. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/cpuidle.h> +#include <linux/clockchips.h> +#include <linux/spinlock.h> +#include <linux/atomic.h> +#include <linux/smp.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include <asm/cpuidle.h> +#include <asm/proc-fns.h> + +static atomic_t master = ATOMIC_INIT(0); +static DEFINE_SPINLOCK(master_lock); +static DEFINE_PER_CPU(struct cpuidle_device, ux500_cpuidle_device); + +static inline int ux500_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int this_cpu = smp_processor_id(); + bool recouple = false; + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &this_cpu); + + if (atomic_inc_return(&master) == num_online_cpus()) { + + /* With this lock, we prevent the other cpu to exit and enter + * this function again and become the master */ + if (!spin_trylock(&master_lock)) + goto wfi; + + /* decouple the gic from the A9 cores */ + if (prcmu_gic_decouple()) + goto out; + + /* If an error occur, we will have to recouple the gic + * manually */ + recouple = true; + + /* At this state, as the gic is decoupled, if the other + * cpu is in WFI, we have the guarantee it won't be wake + * up, so we can safely go to retention */ + if (!prcmu_is_cpu_in_wfi(this_cpu ? 0 : 1)) + goto out; + + /* The prcmu will be in charge of watching the interrupts + * and wake up the cpus */ + if (prcmu_copy_gic_settings()) + goto out; + + /* Check in the meantime an interrupt did + * not occur on the gic ... */ + if (prcmu_gic_pending_irq()) + goto out; + + /* ... and the prcmu */ + if (prcmu_pending_irq()) + goto out; + + /* Go to the retention state, the prcmu will wait for the + * cpu to go WFI and this is what happens after exiting this + * 'master' critical section */ + if (prcmu_set_power_state(PRCMU_AP_IDLE, true, true)) + goto out; + + /* When we switch to retention, the prcmu is in charge + * of recoupling the gic automatically */ + recouple = false; + + spin_unlock(&master_lock); + } +wfi: + cpu_do_idle(); +out: + atomic_dec(&master); + + if (recouple) { + prcmu_gic_recouple(); + spin_unlock(&master_lock); + } + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &this_cpu); + + return index; +} + +static struct cpuidle_driver ux500_idle_driver = { + .name = "ux500_idle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states = { + ARM_CPUIDLE_WFI_STATE, + { + .enter = ux500_enter_idle, + .exit_latency = 70, + .target_residency = 260, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "ApIdle", + .desc = "ARM Retention", + }, + }, + .safe_state_index = 0, + .state_count = 2, +}; + +/* + * For each cpu, setup the broadcast timer because we will + * need to migrate the timers for the states >= ApIdle. + */ +static void ux500_setup_broadcast_timer(void *arg) +{ + int cpu = smp_processor_id(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); +} + +int __init ux500_idle_init(void) +{ + int ret, cpu; + struct cpuidle_device *device; + + /* Configure wake up reasons */ + prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | + PRCMU_WAKEUP(ABB)); + + /* + * Configure the timer broadcast for each cpu, that must + * be done from the cpu context, so we use a smp cross + * call with 'on_each_cpu'. + */ + on_each_cpu(ux500_setup_broadcast_timer, NULL, 1); + + ret = cpuidle_register_driver(&ux500_idle_driver); + if (ret) { + printk(KERN_ERR "failed to register ux500 idle driver\n"); + return ret; + } + + for_each_online_cpu(cpu) { + device = &per_cpu(ux500_cpuidle_device, cpu); + device->cpu = cpu; + ret = cpuidle_register_device(device); + if (ret) { + printk(KERN_ERR "Failed to register cpuidle " + "device for cpu%d\n", cpu); + goto out_unregister; + } + } +out: + return ret; + +out_unregister: + for_each_online_cpu(cpu) { + device = &per_cpu(ux500_cpuidle_device, cpu); + cpuidle_unregister_device(device); + } + + cpuidle_unregister_driver(&ux500_idle_driver); + goto out; +} + +device_initcall(ux500_idle_init); diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c index c76f0f456f0..bf7e81705d2 100644 --- a/arch/arm/mach-ux500/hotplug.c +++ b/arch/arm/mach-ux500/hotplug.c @@ -11,20 +11,31 @@ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/smp.h> +#include <linux/completion.h> #include <asm/cacheflush.h> #include <asm/smp_plat.h> +#include <mach/context.h> + extern volatile int pen_release; +static DECLARE_COMPLETION(cpu_killed); + static inline void platform_do_lowpower(unsigned int cpu) { flush_cache_all(); - /* we put the platform to just WFI */ for (;;) { - __asm__ __volatile__("dsb\n\t" "wfi\n\t" - : : : "memory"); + + context_varm_save_core(); + context_save_cpu_registers(); + + context_save_to_sram_and_wfi(false); + + context_restore_cpu_registers(); + context_varm_restore_core(); + if (pen_release == cpu_logical_map(cpu)) { /* * OK, proper wakeup, we're done @@ -36,7 +47,7 @@ static inline void platform_do_lowpower(unsigned int cpu) int platform_cpu_kill(unsigned int cpu) { - return 1; + return wait_for_completion_timeout(&cpu_killed, 5000); } /* @@ -46,6 +57,19 @@ int platform_cpu_kill(unsigned int cpu) */ void platform_cpu_die(unsigned int cpu) { +#ifdef DEBUG + unsigned int this_cpu = hard_smp_processor_id(); + + if (cpu != this_cpu) { + printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", + this_cpu, cpu); + BUG(); + } +#endif + + printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); + complete(&cpu_killed); + /* directly enter low power state, skipping secure registers */ platform_do_lowpower(cpu); } diff --git a/arch/arm/mach-ux500/include/mach/context.h b/arch/arm/mach-ux500/include/mach/context.h new file mode 100644 index 00000000000..a3490121b67 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/context.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> + * Rickard Andersson <rickard.andersson@stericsson.com> for + * ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2 + * + */ +#ifndef CONTEXT_H +#define CONTEXT_H + +#include <linux/notifier.h> + +#ifdef CONFIG_UX500_CONTEXT + +/* Defines to be with + * context_ape_notifier_register + */ +#define CONTEXT_APE_SAVE 0 /* APE save */ +#define CONTEXT_APE_RESTORE 1 /* APE restore */ + +/* Defines to be with + * context_arm_notifier_register + */ +#define CONTEXT_ARM_CORE_SAVE 0 /* Called for each ARM core */ +#define CONTEXT_ARM_CORE_RESTORE 1 /* Called for each ARM core */ +#define CONTEXT_ARM_COMMON_SAVE 2 /* Called when ARM common is saved */ +#define CONTEXT_ARM_COMMON_RESTORE 3 /* Called when ARM common is restored */ + +int context_ape_notifier_register(struct notifier_block *nb); +int context_ape_notifier_unregister(struct notifier_block *nb); + +int context_arm_notifier_register(struct notifier_block *nb); +int context_arm_notifier_unregister(struct notifier_block *nb); + +void context_vape_save(void); +void context_vape_restore(void); + +void context_fsmc_save(void); +void context_fsmc_restore(void); + +void context_gpio_save(void); +void context_gpio_restore(void); +void context_gpio_restore_mux(void); +void context_gpio_mux_safe_switch(bool begin); + +void context_gic_dist_disable_unneeded_irqs(void); + +void context_varm_save_common(void); +void context_varm_restore_common(void); + +void context_varm_save_core(void); +void context_varm_restore_core(void); + +void context_save_cpu_registers(void); +void context_restore_cpu_registers(void); + +void context_save_to_sram_and_wfi(bool cleanL2cache); + +void context_clean_l1_cache_all(void); +void context_save_arm_registers(u32 **backup_stack); +void context_restore_arm_registers(u32 **backup_stack); + +void context_save_cp15_registers(u32 **backup_stack); +void context_restore_cp15_registers(u32 **backup_stack); + +void context_save_to_sram_and_wfi_internal(u32 backup_sram_storage, + bool cleanL2cache); + +/* DB specific functions in either context-db8500 or context-db5500 */ +void u8500_context_save_icn(void); +void u8500_context_restore_icn(void); +void u8500_context_init(void); + +void u5500_context_save_icn(void); +void u5500_context_restore_icn(void); +void u5500_context_init(void); + +void u9540_context_save_icn(void); +void u9540_context_restore_icn(void); +void u9540_context_init(void); +#else + +static inline void context_varm_save_core(void) {} +static inline void context_save_cpu_registers(void) {} +static inline void context_save_to_sram_and_wfi(bool cleanL2cache) {} +static inline void context_restore_cpu_registers(void) {} +static inline void context_varm_restore_core(void) {} + +#endif + +#endif diff --git a/arch/arm/mach-ux500/include/mach/pm-timer.h b/arch/arm/mach-ux500/include/mach/pm-timer.h new file mode 100644 index 00000000000..f5fafbbaa77 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/pm-timer.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + * + * License Terms: GNU General Public License v2 + * + */ + +#ifndef PM_TIMER_H +#define PM_TIMER_H + +#include <linux/ktime.h> + +#ifdef CONFIG_UX500_CPUIDLE_DEBUG +ktime_t u8500_rtc_exit_latency_get(void); +void ux500_rtcrtt_measure_latency(bool enable); +#else +static inline ktime_t u8500_rtc_exit_latency_get(void) +{ + return ktime_set(0, 0); +} +static inline void ux500_rtcrtt_measure_latency(bool enable) { } + +#endif + +void ux500_rtcrtt_off(void); +void ux500_rtcrtt_next(u32 time_us); + +#endif diff --git a/arch/arm/mach-ux500/include/mach/pm.h b/arch/arm/mach-ux500/include/mach/pm.h new file mode 100644 index 00000000000..c6f1b0adca5 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/pm.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Rickard Andersson <rickard.andersson@stericsson.com> for + * ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#ifndef PM_COMMON_H +#define PM_COMMON_H + +#ifdef CONFIG_PM +#include <linux/mfd/dbx500-prcmu.h> + +/** + * ux500_pm_gic_decouple() + * + * Decouple GIC from the interrupt bus. + */ +void ux500_pm_gic_decouple(void); + +/** + * ux500_pm_gic_recouple() + * + * Recouple GIC with the interrupt bus. + */ +void ux500_pm_gic_recouple(void); + +/** + * ux500_pm_gic_pending_interrupt() + * + * returns true, if there are pending interrupts. + */ +bool ux500_pm_gic_pending_interrupt(void); + +/** + * ux500_pm_prcmu_pending_interrupt() + * + * returns true, if there are pending interrupts. + */ +bool ux500_pm_prcmu_pending_interrupt(void); + +/** + * ux500_pm_prcmu_set_ioforce() + * + * @enable: Enable/disable + * + * Enable/disable the gpio-ring + */ +void ux500_pm_prcmu_set_ioforce(bool enable); + +/** + * ux500_pm_prcmu_copy_gic_settings() + * + * This function copies all the gic interrupt settings to the prcmu. + * This is needed for the system to catch interrupts in ApIdle + */ +void ux500_pm_prcmu_copy_gic_settings(void); + +/** + * ux500_pm_gpio_save_wake_up_status() + * + * This function is called when the prcmu has woken the ARM + * but before ioforce is disabled. + */ +void ux500_pm_gpio_save_wake_up_status(void); + +/** + * ux500_pm_gpio_read_wake_up_status() + * + * @bank_number: The gpio bank. + * + * Returns the WKS register settings for given bank number. + * The WKS register is cleared when ioforce is released therefore + * this function is needed. + */ +u32 ux500_pm_gpio_read_wake_up_status(unsigned int bank_number); + +/** + * ux500_pm_other_cpu_wfi() + * + * Returns true if the other CPU is in WFI. + */ +bool ux500_pm_other_cpu_wfi(void); + +struct dev_pm_domain; +extern struct dev_pm_domain ux500_dev_power_domain; +extern struct dev_pm_domain ux500_amba_dev_power_domain; + +#else +u32 ux500_pm_gpio_read_wake_up_status(unsigned int bank_number) +{ + return 0; +} + +/** + * ux500_pm_prcmu_set_ioforce() + * + * @enable: Enable/disable + * + * Enable/disable the gpio-ring + */ +static inline void ux500_pm_prcmu_set_ioforce(bool enable) { } + +#endif + +extern int ux500_console_uart_gpio_pin; + +#endif diff --git a/arch/arm/mach-ux500/include/mach/prcmu-debug.h b/arch/arm/mach-ux500/include/mach/prcmu-debug.h new file mode 100644 index 00000000000..38f5ad94864 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/prcmu-debug.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * + * Author: Martin Persson for ST-Ericsson + * Etienne Carriere <etienne.carriere@stericsson.com> for ST-Ericsson + * + */ + +#ifndef PRCMU_DEBUG_H +#define PRCMU_DEBUG_H + +#ifdef CONFIG_DBX500_PRCMU_DEBUG +void prcmu_debug_ape_opp_log(u8 opp); +void prcmu_debug_ddr_opp_log(u8 opp); +void prcmu_debug_arm_opp_log(u32 value); +void prcmu_debug_dump_data_mem(void); +void prcmu_debug_dump_regs(void); +void prcmu_debug_register_interrupt(u32 mailbox); +void prcmu_debug_register_mbox0_event(u32 ev, u32 mask); +#else +static inline void prcmu_debug_ape_opp_log(u8 opp) {} +static inline void prcmu_debug_ddr_opp_log(u8 opp) {} +static inline void prcmu_debug_arm_opp_log(u32 value) {} +static inline void prcmu_debug_dump_data_mem(void) {} +static inline void prcmu_debug_dump_regs(void) {} +static inline void prcmu_debug_register_interrupt(u32 mailbox) {} +static inline void prcmu_debug_register_mbox0_event(u32 ev, u32 mask) {} +#endif +#endif diff --git a/arch/arm/mach-ux500/include/mach/suspend.h b/arch/arm/mach-ux500/include/mach/suspend.h new file mode 100644 index 00000000000..5a8df72be2e --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/suspend.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef __MACH_SUSPEND_H +#define __MACH_SUSPEND_H + +#ifdef CONFIG_UX500_SUSPEND +void suspend_block_sleep(void); +void suspend_unblock_sleep(void); +void suspend_set_pins_force_fn(void (*force)(void), void (*force_mux)(void)); +#else +static inline void suspend_block_sleep(void) { } +static inline void suspend_unblock_sleep(void) { } +static inline void suspend_set_pins_force_fn(void (*force)(void), + void (*force_mux)(void)) { } +#endif + +#endif /* __MACH_SUSPEND_H */ diff --git a/arch/arm/mach-ux500/pm/Kconfig b/arch/arm/mach-ux500/pm/Kconfig new file mode 100644 index 00000000000..12004ba9858 --- /dev/null +++ b/arch/arm/mach-ux500/pm/Kconfig @@ -0,0 +1,70 @@ +config DBX500_PRCMU_QOS_POWER + bool "DBX500 PRCMU power QoS support" + depends on (MFD_DB5500_PRCMU || MFD_DB8500_PRCMU) + default y + help + Add support for PRCMU power Quality of Service + +config UX500_CONTEXT + bool "Context save/restore support for UX500" + depends on (UX500_SOC_DB8500 || UX500_SOC_DB5500) && PM + help + This is needed for ApSleep and deeper sleep states. + +config UX500_PM_PERFORMANCE + bool "Performance supervision" + depends on DBX500_PRCMU_QOS_POWER + default y + help + Enable supervision of events which may require a boost + of platform performance. + +config UX500_CONSOLE_UART_GPIO_PIN + int "The pin number of the console UART GPIO pin" + default 29 + depends on UX500_SUSPEND_DBG_WAKE_ON_UART || UX500_CPUIDLE_DEBUG + help + GPIO pin number of the GPIO pin connected to the console UART RX line. + + Board-specific code can change this. + +config UX500_SUSPEND + bool "Suspend to mem and standby support" + depends on (UX500_SOC_DB8500 || UX500_SOC_DB5500) && PM && SUSPEND + select UX500_CONTEXT + help + Add support for suspend. + +config UX500_SUSPEND_STANDBY + bool "Suspend Standby goes to ApSleep" + depends on UX500_SUSPEND + help + If yes, echo standby > /sys/power/state puts the system into ApSleep. + +config UX500_SUSPEND_MEM + bool "Suspend Mem goes to ApDeepSleep" + depends on UX500_SUSPEND + help + If yes, echo mem > /sys/power/state puts the system into ApDeepSleep else + it will do the same as echo standby > /sys/power/state. + +config UX500_SUSPEND_DBG + bool "Suspend debug" + depends on UX500_SUSPEND && DEBUG_FS + help + Add debug support for suspend. + +config UX500_SUSPEND_DBG_WAKE_ON_UART + bool "Suspend wakes on console UART" + depends on UX500_SUSPEND_DBG + help + Wake up on uart interrupts. Makes it possible for the console to wake up system. + +config UX500_USECASE_GOVERNOR + bool "UX500 use-case governor" + depends on (UX500_SOC_DB8500 || UX500_SOC_DB5500) && \ + (CPU_FREQ && CPU_IDLE && HOTPLUG_CPU && \ + EARLYSUSPEND && UX500_L2X0_PREFETCH_CTRL && PM) + default y + help + Adjusts CPU_IDLE, CPU_FREQ, HOTPLUG_CPU and L2 cache parameters diff --git a/arch/arm/mach-ux500/pm/Makefile b/arch/arm/mach-ux500/pm/Makefile new file mode 100644 index 00000000000..ef33bdf0d4e --- /dev/null +++ b/arch/arm/mach-ux500/pm/Makefile @@ -0,0 +1,12 @@ +# +# Power save related files +# +obj-y := pm.o runtime.o + +obj-$(CONFIG_DBX500_PRCMU_QOS_POWER) += prcmu-qos-power.o +obj-$(CONFIG_UX500_CONTEXT) += context.o context_arm.o context-db8500.o context-db5500.o context-db9540.o +obj-$(CONFIG_UX500_CPUIDLE) += timer.o +obj-$(CONFIG_UX500_SUSPEND) += suspend.o +obj-$(CONFIG_UX500_SUSPEND_DBG) += suspend_dbg.o +obj-$(CONFIG_UX500_PM_PERFORMANCE) += performance.o +obj-$(CONFIG_UX500_USECASE_GOVERNOR) += usecase_gov.o diff --git a/arch/arm/mach-ux500/pm/context-db5500.c b/arch/arm/mach-ux500/pm/context-db5500.c new file mode 100644 index 00000000000..9842785c05a --- /dev/null +++ b/arch/arm/mach-ux500/pm/context-db5500.c @@ -0,0 +1,407 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com>, + * Rickard Andersson <rickard.andersson@stericsson.com>, + * Sundar Iyer <sundar.iyer@stericsson.com>, + * ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/context.h> + +/* These registers are DB5500 specific */ +#define NODE_HIBW1_ESRAM_IN_0_PRIORITY 0x0 +#define NODE_HIBW1_ESRAM_IN_1_PRIORITY 0x4 + +#define NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT 0x18 +#define NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT 0x1C +#define NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT 0x20 + +#define NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT 0x24 +#define NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT 0x28 +#define NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT 0x2C + +#define NODE_HIBW1_DDR_IN_0_PRIORITY 0x400 +#define NODE_HIBW1_DDR_IN_1_PRIORITY 0x404 +#define NODE_HIBW1_DDR_IN_2_PRIORITY 0x408 + +#define NODE_HIBW1_DDR_IN_0_LIMIT 0x424 +#define NODE_HIBW1_DDR_IN_1_LIMIT 0x428 +#define NODE_HIBW1_DDR_IN_2_LIMIT 0x42C + +#define NODE_HIBW1_DDR_OUT_0_PRIORITY 0x430 + +#define NODE_HIBW2_ESRAM_IN_0_PRIORITY 0x800 +#define NODE_HIBW2_ESRAM_IN_1_PRIORITY 0x804 + +#define NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT 0x818 +#define NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT 0x81C +#define NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT 0x820 + +#define NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT 0x824 +#define NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT 0x828 +#define NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT 0x82C + +#define NODE_HIBW2_DDR_IN_0_PRIORITY 0xC00 +#define NODE_HIBW2_DDR_IN_1_PRIORITY 0xC04 +#define NODE_HIBW2_DDR_IN_2_PRIORITY 0xC08 +#define NODE_HIBW2_DDR_IN_3_PRIORITY 0xC0C + +#define NODE_HIBW2_DDR_IN_0_LIMIT 0xC30 +#define NODE_HIBW2_DDR_IN_1_LIMIT 0xC34 +#define NODE_HIBW2_DDR_IN_2_LIMIT 0xC38 +#define NODE_HIBW2_DDR_IN_3_LIMIT 0xC3C + +#define NODE_HIBW2_DDR_OUT_0_PRIORITY 0xC40 + +#define NODE_ESRAM0_IN_0_PRIORITY 0x1000 +#define NODE_ESRAM0_IN_1_PRIORITY 0x1004 +#define NODE_ESRAM0_IN_2_PRIORITY 0x1008 + +#define NODE_ESRAM0_IN_0_LIMIT 0x1024 +#define NODE_ESRAM0_IN_1_LIMIT 0x1028 +#define NODE_ESRAM0_IN_2_LIMIT 0x102C +#define NODE_ESRAM0_OUT_0_PRIORITY 0x1030 + +#define NODE_ESRAM1_2_IN_0_PRIORITY 0x1400 +#define NODE_ESRAM1_2_IN_1_PRIORITY 0x1404 +#define NODE_ESRAM1_2_IN_2_PRIORITY 0x1408 + +#define NODE_ESRAM1_2_IN_0_ARB_1_LIMIT 0x1424 +#define NODE_ESRAM1_2_IN_1_ARB_1_LIMIT 0x1428 +#define NODE_ESRAM1_2_IN_2_ARB_1_LIMIT 0x142C +#define NODE_ESRAM1_2_OUT_0_PRIORITY 0x1430 + +#define NODE_ESRAM3_4_IN_0_PRIORITY 0x1800 +#define NODE_ESRAM3_4_IN_1_PRIORITY 0x1804 +#define NODE_ESRAM3_4_IN_2_PRIORITY 0x1808 + +#define NODE_ESRAM3_4_IN_0_ARB_1_LIMIT 0x1824 +#define NODE_ESRAM3_4_IN_1_ARB_1_LIMIT 0x1828 +#define NODE_ESRAM3_4_IN_2_ARB_1_LIMIT 0x182C +#define NODE_ESRAM3_4_OUT_0_PRIORITY 0x1830 + +/* + * Save ICN (Interconnect or Interconnect nodes) configuration registers + * TODO: This can be optimized, for example if we have + * a static ICN configuration. + */ + +static struct { + void __iomem *base; + u32 hibw1_esram_in_pri[2]; + u32 hibw1_esram_in0_arb[3]; + u32 hibw1_esram_in1_arb[3]; + u32 hibw1_ddr_in_prio[3]; + u32 hibw1_ddr_in_limit[3]; + u32 hibw1_ddr_out_prio_reg; + + /* HiBw2 node registers */ + u32 hibw2_esram_in_pri[2]; + u32 hibw2_esram_in0_arblimit[3]; + u32 hibw2_esram_in1_arblimit[3]; + u32 hibw2_ddr_in_prio[4]; + u32 hibw2_ddr_in_limit[4]; + u32 hibw2_ddr_out_prio_reg; + + /* ESRAM node registers */ + u32 esram_in_prio[3]; + u32 esram_in_lim[3]; + u32 esram_out_prio_reg; + + u32 esram12_in_prio[3]; + u32 esram12_in_arb_lim[3]; + u32 esram12_out_prio_reg; + + u32 esram34_in_prio[3]; + u32 esram34_in_arb_lim[3]; + u32 esram34_out_prio; +} context_icn; + + +void u5500_context_save_icn(void) +{ + void __iomem *base = context_icn.base; + + /* hibw1 */ + context_icn.hibw1_esram_in_pri[0] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_0_PRIORITY); + context_icn.hibw1_esram_in_pri[1] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_1_PRIORITY); + + context_icn.hibw1_esram_in0_arb[0] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT); + context_icn.hibw1_esram_in0_arb[1] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT); + context_icn.hibw1_esram_in0_arb[2] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT); + + context_icn.hibw1_esram_in1_arb[0] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT); + context_icn.hibw1_esram_in1_arb[1] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT); + context_icn.hibw1_esram_in1_arb[2] = + readl_relaxed(base + NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT); + + context_icn.hibw1_ddr_in_prio[0] = + readl_relaxed(base + NODE_HIBW1_DDR_IN_0_PRIORITY); + context_icn.hibw1_ddr_in_prio[1] = + readl_relaxed(base + NODE_HIBW1_DDR_IN_1_PRIORITY); + context_icn.hibw1_ddr_in_prio[2] = + readl_relaxed(base + NODE_HIBW1_DDR_IN_2_PRIORITY); + + context_icn.hibw1_ddr_in_limit[0] = + readl_relaxed(base + NODE_HIBW1_DDR_IN_0_LIMIT); + context_icn.hibw1_ddr_in_limit[1] = + readl_relaxed(base + NODE_HIBW1_DDR_IN_1_LIMIT); + context_icn.hibw1_ddr_in_limit[2] = + readl_relaxed(base + NODE_HIBW1_DDR_IN_2_LIMIT); + + context_icn.hibw1_ddr_out_prio_reg = + readl_relaxed(base + NODE_HIBW1_DDR_OUT_0_PRIORITY); + + /* hibw2 */ + context_icn.hibw2_esram_in_pri[0] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_0_PRIORITY); + context_icn.hibw2_esram_in_pri[1] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_1_PRIORITY); + + context_icn.hibw2_esram_in0_arblimit[0] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT); + context_icn.hibw2_esram_in0_arblimit[1] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT); + context_icn.hibw2_esram_in0_arblimit[2] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT); + + context_icn.hibw2_esram_in1_arblimit[0] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT); + context_icn.hibw2_esram_in1_arblimit[1] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT); + context_icn.hibw2_esram_in1_arblimit[2] = + readl_relaxed(base + NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT); + + context_icn.hibw2_ddr_in_prio[0] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_0_PRIORITY); + context_icn.hibw2_ddr_in_prio[1] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_1_PRIORITY); + context_icn.hibw2_ddr_in_prio[2] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_2_PRIORITY); + context_icn.hibw2_ddr_in_prio[3] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_3_PRIORITY); + + context_icn.hibw2_ddr_in_limit[0] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_0_LIMIT); + context_icn.hibw2_ddr_in_limit[1] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_1_LIMIT); + context_icn.hibw2_ddr_in_limit[2] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_2_LIMIT); + context_icn.hibw2_ddr_in_limit[3] = + readl_relaxed(base + NODE_HIBW2_DDR_IN_3_LIMIT); + + context_icn.hibw2_ddr_out_prio_reg = + readl_relaxed(base + NODE_HIBW2_DDR_OUT_0_PRIORITY); + + /* ESRAM0 */ + context_icn.esram_in_prio[0] = + readl_relaxed(base + NODE_ESRAM0_IN_0_PRIORITY); + context_icn.esram_in_prio[1] = + readl_relaxed(base + NODE_ESRAM0_IN_1_PRIORITY); + context_icn.esram_in_prio[2] = + readl_relaxed(base + NODE_ESRAM0_IN_2_PRIORITY); + + context_icn.esram_in_lim[0] = + readl_relaxed(base + NODE_ESRAM0_IN_0_LIMIT); + context_icn.esram_in_lim[1] = + readl_relaxed(base + NODE_ESRAM0_IN_1_LIMIT); + context_icn.esram_in_lim[2] = + readl_relaxed(base + NODE_ESRAM0_IN_2_LIMIT); + + context_icn.esram_out_prio_reg = + readl_relaxed(base + NODE_ESRAM0_OUT_0_PRIORITY); + + /* ESRAM1-2 */ + context_icn.esram12_in_prio[0] = + readl_relaxed(base + NODE_ESRAM1_2_IN_0_PRIORITY); + context_icn.esram12_in_prio[1] = + readl_relaxed(base + NODE_ESRAM1_2_IN_1_PRIORITY); + context_icn.esram12_in_prio[2] = + readl_relaxed(base + NODE_ESRAM1_2_IN_2_PRIORITY); + + context_icn.esram12_in_arb_lim[0] = + readl_relaxed(base + NODE_ESRAM1_2_IN_0_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[1] = + readl_relaxed(base + NODE_ESRAM1_2_IN_1_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[2] = + readl_relaxed(base + NODE_ESRAM1_2_IN_2_ARB_1_LIMIT); + + context_icn.esram12_out_prio_reg = + readl_relaxed(base + NODE_ESRAM1_2_OUT_0_PRIORITY); + + /* ESRAM3-4 */ + context_icn.esram34_in_prio[0] = + readl_relaxed(base + NODE_ESRAM3_4_IN_0_PRIORITY); + context_icn.esram34_in_prio[1] = + readl_relaxed(base + NODE_ESRAM3_4_IN_1_PRIORITY); + context_icn.esram34_in_prio[2] = + readl_relaxed(base + NODE_ESRAM3_4_IN_2_PRIORITY); + + context_icn.esram34_in_arb_lim[0] = + readl_relaxed(base + NODE_ESRAM3_4_IN_0_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[1] = + readl_relaxed(base + NODE_ESRAM3_4_IN_1_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[2] = + readl_relaxed(base + NODE_ESRAM3_4_IN_2_ARB_1_LIMIT); + + context_icn.esram34_out_prio = + readl_relaxed(base + NODE_ESRAM3_4_OUT_0_PRIORITY); +} + +/* + * Restore ICN configuration registers + */ +void u5500_context_restore_icn(void) +{ + void __iomem *base = context_icn.base; + + /* hibw1 */ + writel_relaxed(context_icn.hibw1_esram_in_pri[0], + base + NODE_HIBW1_ESRAM_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw1_esram_in_pri[1], + base + NODE_HIBW1_ESRAM_IN_1_PRIORITY); + + writel_relaxed(context_icn.hibw1_esram_in0_arb[0], + base + NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in0_arb[1], + base + NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in0_arb[2], + base + NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_esram_in1_arb[0], + base + NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in1_arb[1], + base + NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in1_arb[2], + base + NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_ddr_in_prio[0], + base + NODE_HIBW1_DDR_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr_in_prio[1], + base + NODE_HIBW1_DDR_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr_in_prio[2], + base + NODE_HIBW1_DDR_IN_2_PRIORITY); + + writel_relaxed(context_icn.hibw1_ddr_in_limit[0], + base + NODE_HIBW1_DDR_IN_0_LIMIT); + writel_relaxed(context_icn.hibw1_ddr_in_limit[1], + base + NODE_HIBW1_DDR_IN_1_LIMIT); + writel_relaxed(context_icn.hibw1_ddr_in_limit[2], + base + NODE_HIBW1_DDR_IN_2_LIMIT); + + writel_relaxed(context_icn.hibw1_ddr_out_prio_reg, + base + NODE_HIBW1_DDR_OUT_0_PRIORITY); + + /* hibw2 */ + writel_relaxed(context_icn.hibw2_esram_in_pri[0], + base + NODE_HIBW2_ESRAM_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw2_esram_in_pri[1], + base + NODE_HIBW2_ESRAM_IN_1_PRIORITY); + + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[0], + base + NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[1], + base + NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[2], + base + NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[0], + base + NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[1], + base + NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[2], + base + NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw2_ddr_in_prio[0], + base + NODE_HIBW2_DDR_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr_in_prio[1], + base + NODE_HIBW2_DDR_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr_in_prio[2], + base + NODE_HIBW2_DDR_IN_2_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr_in_prio[3], + base + NODE_HIBW2_DDR_IN_3_PRIORITY); + + writel_relaxed(context_icn.hibw2_ddr_in_limit[0], + base + NODE_HIBW2_DDR_IN_0_LIMIT); + writel_relaxed(context_icn.hibw2_ddr_in_limit[1], + base + NODE_HIBW2_DDR_IN_1_LIMIT); + writel_relaxed(context_icn.hibw2_ddr_in_limit[2], + base + NODE_HIBW2_DDR_IN_2_LIMIT); + writel_relaxed(context_icn.hibw2_ddr_in_limit[3], + base + NODE_HIBW2_DDR_IN_3_LIMIT); + + writel_relaxed(context_icn.hibw2_ddr_out_prio_reg, + base + NODE_HIBW2_DDR_OUT_0_PRIORITY); + + /* ESRAM0 */ + writel_relaxed(context_icn.esram_in_prio[0], + base + NODE_ESRAM0_IN_0_PRIORITY); + writel_relaxed(context_icn.esram_in_prio[1], + base + NODE_ESRAM0_IN_1_PRIORITY); + writel_relaxed(context_icn.esram_in_prio[2], + base + NODE_ESRAM0_IN_2_PRIORITY); + + writel_relaxed(context_icn.esram_in_lim[0], + base + NODE_ESRAM0_IN_0_LIMIT); + writel_relaxed(context_icn.esram_in_lim[1], + base + NODE_ESRAM0_IN_1_LIMIT); + writel_relaxed(context_icn.esram_in_lim[2], + base + NODE_ESRAM0_IN_2_LIMIT); + + writel_relaxed(context_icn.esram_out_prio_reg, + base + NODE_ESRAM0_OUT_0_PRIORITY); + + /* ESRAM1-2 */ + writel_relaxed(context_icn.esram12_in_prio[0], + base + NODE_ESRAM1_2_IN_0_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[1], + base + NODE_ESRAM1_2_IN_1_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[2], + base + NODE_ESRAM1_2_IN_2_PRIORITY); + + writel_relaxed(context_icn.esram12_in_arb_lim[0], + base + NODE_ESRAM1_2_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[1], + base + NODE_ESRAM1_2_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[2], + base + NODE_ESRAM1_2_IN_2_ARB_1_LIMIT); + + writel_relaxed(context_icn.esram12_out_prio_reg, + base + NODE_ESRAM1_2_OUT_0_PRIORITY); + + /* ESRAM3-4 */ + writel_relaxed(context_icn.esram34_in_prio[0], + base + NODE_ESRAM3_4_IN_0_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[1], + base + NODE_ESRAM3_4_IN_1_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[2], + base + NODE_ESRAM3_4_IN_2_PRIORITY); + + writel_relaxed(context_icn.esram34_in_arb_lim[0], + base + NODE_ESRAM3_4_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[1], + base + NODE_ESRAM3_4_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[2], + base + NODE_ESRAM3_4_IN_2_ARB_1_LIMIT); + + writel_relaxed(context_icn.esram34_out_prio, + base + NODE_ESRAM3_4_OUT_0_PRIORITY); + +} + +void u5500_context_init(void) +{ + context_icn.base = ioremap(U5500_ICN_BASE, SZ_8K); +} diff --git a/arch/arm/mach-ux500/pm/context-db8500.c b/arch/arm/mach-ux500/pm/context-db8500.c new file mode 100644 index 00000000000..3ba73e51a6d --- /dev/null +++ b/arch/arm/mach-ux500/pm/context-db8500.c @@ -0,0 +1,456 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * License Terms: GNU General Public License v2 + * Author: Sundar Iyer for ST-Ericsson + * + */ + +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/context.h> + +/* + * ST-Interconnect context + */ + +/* priority, bw limiter register offsets */ +#define NODE_HIBW1_ESRAM_IN_0_PRIORITY 0x00 +#define NODE_HIBW1_ESRAM_IN_1_PRIORITY 0x04 +#define NODE_HIBW1_ESRAM_IN_2_PRIORITY 0x08 +#define NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT 0x24 +#define NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT 0x28 +#define NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT 0x2C +#define NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT 0x30 +#define NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT 0x34 +#define NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT 0x38 +#define NODE_HIBW1_ESRAM_IN_2_ARB_1_LIMIT 0x3C +#define NODE_HIBW1_ESRAM_IN_2_ARB_2_LIMIT 0x40 +#define NODE_HIBW1_ESRAM_IN_2_ARB_3_LIMIT 0x44 +#define NODE_HIBW1_DDR_IN_0_PRIORITY 0x400 +#define NODE_HIBW1_DDR_IN_1_PRIORITY 0x404 +#define NODE_HIBW1_DDR_IN_2_PRIORITY 0x408 +#define NODE_HIBW1_DDR_IN_0_LIMIT 0x424 +#define NODE_HIBW1_DDR_IN_1_LIMIT 0x428 +#define NODE_HIBW1_DDR_IN_2_LIMIT 0x42C +#define NODE_HIBW1_DDR_OUT_0_PRIORITY 0x430 +#define NODE_HIBW2_ESRAM_IN_0_PRIORITY 0x800 +#define NODE_HIBW2_ESRAM_IN_1_PRIORITY 0x804 +#define NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT 0x818 +#define NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT 0x81C +#define NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT 0x820 +#define NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT 0x824 +#define NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT 0x828 +#define NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT 0x82C +#define NODE_HIBW2_DDR_IN_0_PRIORITY 0xC00 +#define NODE_HIBW2_DDR_IN_1_PRIORITY 0xC04 +#define NODE_HIBW2_DDR_IN_2_PRIORITY 0xC08 + +#define NODE_HIBW2_DDR_IN_0_LIMIT 0xC24 +#define NODE_HIBW2_DDR_IN_1_LIMIT 0xC28 +#define NODE_HIBW2_DDR_IN_2_LIMIT 0xC2C +#define NODE_HIBW2_DDR_OUT_0_PRIORITY 0xC30 + +/* + * Note the following addresses are presented in + * db8500 design spec v3.1 and v3.3, table 10. + * But their addresses are not the same as in the + * description. The addresses in the description + * of each registers are correct. + * NODE_HIBW2_DDR_IN_3_LIMIT is only present in v1. + * + * Faulty registers addresses in table 10: + * NODE_HIBW2_DDR_IN_2_LIMIT 0xC38 + * NODE_HIBW2_DDR_IN_3_LIMIT 0xC3C + * NODE_HIBW2_DDR_OUT_0_PRIORITY 0xC40 + */ + +#define NODE_ESRAM0_IN_0_PRIORITY 0x1000 +#define NODE_ESRAM0_IN_1_PRIORITY 0x1004 +#define NODE_ESRAM0_IN_2_PRIORITY 0x1008 +#define NODE_ESRAM0_IN_3_PRIORITY 0x100C +#define NODE_ESRAM0_IN_0_LIMIT 0x1030 +#define NODE_ESRAM0_IN_1_LIMIT 0x1034 +#define NODE_ESRAM0_IN_2_LIMIT 0x1038 +#define NODE_ESRAM0_IN_3_LIMIT 0x103C +/* common */ +#define NODE_ESRAM1_2_IN_0_PRIORITY 0x1400 +#define NODE_ESRAM1_2_IN_1_PRIORITY 0x1404 +#define NODE_ESRAM1_2_IN_2_PRIORITY 0x1408 +#define NODE_ESRAM1_2_IN_3_PRIORITY 0x140C +#define NODE_ESRAM1_2_IN_0_ARB_1_LIMIT 0x1430 +#define NODE_ESRAM1_2_IN_0_ARB_2_LIMIT 0x1434 +#define NODE_ESRAM1_2_IN_1_ARB_1_LIMIT 0x1438 +#define NODE_ESRAM1_2_IN_1_ARB_2_LIMIT 0x143C +#define NODE_ESRAM1_2_IN_2_ARB_1_LIMIT 0x1440 +#define NODE_ESRAM1_2_IN_2_ARB_2_LIMIT 0x1444 +#define NODE_ESRAM1_2_IN_3_ARB_1_LIMIT 0x1448 +#define NODE_ESRAM1_2_IN_3_ARB_2_LIMIT 0x144C + +#define NODE_ESRAM3_4_IN_0_PRIORITY 0x1800 +#define NODE_ESRAM3_4_IN_1_PRIORITY 0x1804 +#define NODE_ESRAM3_4_IN_2_PRIORITY 0x1808 +#define NODE_ESRAM3_4_IN_3_PRIORITY 0x180C +#define NODE_ESRAM3_4_IN_0_ARB_1_LIMIT 0x1830 +#define NODE_ESRAM3_4_IN_0_ARB_2_LIMIT 0x1834 +#define NODE_ESRAM3_4_IN_1_ARB_1_LIMIT 0x1838 +#define NODE_ESRAM3_4_IN_1_ARB_2_LIMIT 0x183C +#define NODE_ESRAM3_4_IN_2_ARB_1_LIMIT 0x1840 +#define NODE_ESRAM3_4_IN_2_ARB_2_LIMIT 0x1844 +#define NODE_ESRAM3_4_IN_3_ARB_1_LIMIT 0x1848 +#define NODE_ESRAM3_4_IN_3_ARB_2_LIMIT 0x184C + +static struct { + void __iomem *base; + u32 hibw1_esram_in_pri[3]; + u32 hibw1_esram_in0_arb[3]; + u32 hibw1_esram_in1_arb[3]; + u32 hibw1_esram_in2_arb[3]; + u32 hibw1_ddr_in_prio[3]; + u32 hibw1_ddr_in_limit[3]; + u32 hibw1_ddr_out_prio; + + /* HiBw2 node registers */ + u32 hibw2_esram_in_pri[2]; + u32 hibw2_esram_in0_arblimit[3]; + u32 hibw2_esram_in1_arblimit[3]; + u32 hibw2_ddr_in_prio[4]; + u32 hibw2_ddr_in_limit[4]; + u32 hibw2_ddr_out_prio; + + /* ESRAM node registers */ + u32 esram_in_prio[4]; + u32 esram_in_lim[4]; + u32 esram0_in_prio[4]; + u32 esram0_in_lim[4]; + u32 esram12_in_prio[4]; + u32 esram12_in_arb_lim[8]; + u32 esram34_in_prio[4]; + u32 esram34_in_arb_lim[8]; +} context_icn; + +/** + * u8500_context_save_icn() - save ICN context + * + */ +void u8500_context_save_icn(void) +{ + void __iomem *b = context_icn.base; + + context_icn.hibw1_esram_in_pri[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_PRIORITY); + context_icn.hibw1_esram_in_pri[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_PRIORITY); + context_icn.hibw1_esram_in_pri[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_PRIORITY); + + context_icn.hibw1_esram_in0_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT); + context_icn.hibw1_esram_in0_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT); + context_icn.hibw1_esram_in0_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT); + + context_icn.hibw1_esram_in1_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT); + context_icn.hibw1_esram_in1_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT); + context_icn.hibw1_esram_in1_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT); + + context_icn.hibw1_esram_in2_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_ARB_1_LIMIT); + context_icn.hibw1_esram_in2_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_ARB_2_LIMIT); + context_icn.hibw1_esram_in2_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_ARB_3_LIMIT); + + context_icn.hibw1_ddr_in_prio[0] = + readl_relaxed(b + NODE_HIBW1_DDR_IN_0_PRIORITY); + context_icn.hibw1_ddr_in_prio[1] = + readl_relaxed(b + NODE_HIBW1_DDR_IN_1_PRIORITY); + context_icn.hibw1_ddr_in_prio[2] = + readl_relaxed(b + NODE_HIBW1_DDR_IN_2_PRIORITY); + + context_icn.hibw1_ddr_in_limit[0] = + readl_relaxed(b + NODE_HIBW1_DDR_IN_0_LIMIT); + context_icn.hibw1_ddr_in_limit[1] = + readl_relaxed(b + NODE_HIBW1_DDR_IN_1_LIMIT); + context_icn.hibw1_ddr_in_limit[2] = + readl_relaxed(b + NODE_HIBW1_DDR_IN_2_LIMIT); + + context_icn.hibw1_ddr_out_prio = + readl_relaxed(b + NODE_HIBW1_DDR_OUT_0_PRIORITY); + + context_icn.hibw2_esram_in_pri[0] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_PRIORITY); + context_icn.hibw2_esram_in_pri[1] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_PRIORITY); + + context_icn.hibw2_esram_in0_arblimit[0] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT); + context_icn.hibw2_esram_in0_arblimit[1] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT); + context_icn.hibw2_esram_in0_arblimit[2] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT); + + context_icn.hibw2_esram_in1_arblimit[0] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT); + context_icn.hibw2_esram_in1_arblimit[1] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT); + context_icn.hibw2_esram_in1_arblimit[2] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT); + + context_icn.hibw2_ddr_in_prio[0] = + readl_relaxed(b + NODE_HIBW2_DDR_IN_0_PRIORITY); + context_icn.hibw2_ddr_in_prio[1] = + readl_relaxed(b + NODE_HIBW2_DDR_IN_1_PRIORITY); + context_icn.hibw2_ddr_in_prio[2] = + readl_relaxed(b + NODE_HIBW2_DDR_IN_2_PRIORITY); + + context_icn.hibw2_ddr_in_limit[0] = + readl_relaxed(b + NODE_HIBW2_DDR_IN_0_LIMIT); + context_icn.hibw2_ddr_in_limit[1] = + readl_relaxed(b + NODE_HIBW2_DDR_IN_1_LIMIT); + + context_icn.hibw2_ddr_in_limit[2] = + readl_relaxed(b + NODE_HIBW2_DDR_IN_2_LIMIT); + + context_icn.hibw2_ddr_out_prio = + readl_relaxed(b + NODE_HIBW2_DDR_OUT_0_PRIORITY); + + context_icn.esram0_in_prio[0] = + readl_relaxed(b + NODE_ESRAM0_IN_0_PRIORITY); + context_icn.esram0_in_prio[1] = + readl_relaxed(b + NODE_ESRAM0_IN_1_PRIORITY); + context_icn.esram0_in_prio[2] = + readl_relaxed(b + NODE_ESRAM0_IN_2_PRIORITY); + context_icn.esram0_in_prio[3] = + readl_relaxed(b + NODE_ESRAM0_IN_3_PRIORITY); + + context_icn.esram0_in_lim[0] = + readl_relaxed(b + NODE_ESRAM0_IN_0_LIMIT); + context_icn.esram0_in_lim[1] = + readl_relaxed(b + NODE_ESRAM0_IN_1_LIMIT); + context_icn.esram0_in_lim[2] = + readl_relaxed(b + NODE_ESRAM0_IN_2_LIMIT); + context_icn.esram0_in_lim[3] = + readl_relaxed(b + NODE_ESRAM0_IN_3_LIMIT); + + context_icn.esram12_in_prio[0] = + readl_relaxed(b + NODE_ESRAM1_2_IN_0_PRIORITY); + context_icn.esram12_in_prio[1] = + readl_relaxed(b + NODE_ESRAM1_2_IN_1_PRIORITY); + context_icn.esram12_in_prio[2] = + readl_relaxed(b + NODE_ESRAM1_2_IN_2_PRIORITY); + context_icn.esram12_in_prio[3] = + readl_relaxed(b + NODE_ESRAM1_2_IN_3_PRIORITY); + + context_icn.esram12_in_arb_lim[0] = + readl_relaxed(b + NODE_ESRAM1_2_IN_0_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[1] = + readl_relaxed(b + NODE_ESRAM1_2_IN_0_ARB_2_LIMIT); + context_icn.esram12_in_arb_lim[2] = + readl_relaxed(b + NODE_ESRAM1_2_IN_1_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[3] = + readl_relaxed(b + NODE_ESRAM1_2_IN_1_ARB_2_LIMIT); + context_icn.esram12_in_arb_lim[4] = + readl_relaxed(b + NODE_ESRAM1_2_IN_2_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[5] = + readl_relaxed(b + NODE_ESRAM1_2_IN_2_ARB_2_LIMIT); + context_icn.esram12_in_arb_lim[6] = + readl_relaxed(b + NODE_ESRAM1_2_IN_3_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[7] = + readl_relaxed(b + NODE_ESRAM1_2_IN_3_ARB_2_LIMIT); + + context_icn.esram34_in_prio[0] = + readl_relaxed(b + NODE_ESRAM3_4_IN_0_PRIORITY); + context_icn.esram34_in_prio[1] = + readl_relaxed(b + NODE_ESRAM3_4_IN_1_PRIORITY); + context_icn.esram34_in_prio[2] = + readl_relaxed(b + NODE_ESRAM3_4_IN_2_PRIORITY); + context_icn.esram34_in_prio[3] = + readl_relaxed(b + NODE_ESRAM3_4_IN_3_PRIORITY); + + context_icn.esram34_in_arb_lim[0] = + readl_relaxed(b + NODE_ESRAM3_4_IN_0_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[1] = + readl_relaxed(b + NODE_ESRAM3_4_IN_0_ARB_2_LIMIT); + context_icn.esram34_in_arb_lim[2] = + readl_relaxed(b + NODE_ESRAM3_4_IN_1_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[3] = + readl_relaxed(b + NODE_ESRAM3_4_IN_1_ARB_2_LIMIT); + context_icn.esram34_in_arb_lim[4] = + readl_relaxed(b + NODE_ESRAM3_4_IN_2_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[5] = + readl_relaxed(b + NODE_ESRAM3_4_IN_2_ARB_2_LIMIT); + context_icn.esram34_in_arb_lim[6] = + readl_relaxed(b + NODE_ESRAM3_4_IN_3_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[7] = + readl_relaxed(b + NODE_ESRAM3_4_IN_3_ARB_2_LIMIT); +} + +/** + * u8500_context_restore_icn() - restore ICN context + * + */ +void u8500_context_restore_icn(void) +{ + void __iomem *b = context_icn.base; + + writel_relaxed(context_icn.hibw1_esram_in_pri[0], + b + NODE_HIBW1_ESRAM_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw1_esram_in_pri[1], + b + NODE_HIBW1_ESRAM_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw1_esram_in_pri[2], + b + NODE_HIBW1_ESRAM_IN_2_PRIORITY); + + writel_relaxed(context_icn.hibw1_esram_in0_arb[0], + b + NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in0_arb[1], + b + NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in0_arb[2], + b + NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_esram_in1_arb[0], + b + NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in1_arb[1], + b + NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in1_arb[2], + b + NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_esram_in2_arb[0], + b + NODE_HIBW1_ESRAM_IN_2_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in2_arb[1], + b + NODE_HIBW1_ESRAM_IN_2_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in2_arb[2], + b + NODE_HIBW1_ESRAM_IN_2_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_ddr_in_prio[0], + b + NODE_HIBW1_DDR_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr_in_prio[1], + b + NODE_HIBW1_DDR_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr_in_prio[2], + b + NODE_HIBW1_DDR_IN_2_PRIORITY); + + writel_relaxed(context_icn.hibw1_ddr_in_limit[0], + b + NODE_HIBW1_DDR_IN_0_LIMIT); + writel_relaxed(context_icn.hibw1_ddr_in_limit[1], + b + NODE_HIBW1_DDR_IN_1_LIMIT); + writel_relaxed(context_icn.hibw1_ddr_in_limit[2], + b + NODE_HIBW1_DDR_IN_2_LIMIT); + + writel_relaxed(context_icn.hibw1_ddr_out_prio, + b + NODE_HIBW1_DDR_OUT_0_PRIORITY); + + writel_relaxed(context_icn.hibw2_esram_in_pri[0], + b + NODE_HIBW2_ESRAM_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw2_esram_in_pri[1], + b + NODE_HIBW2_ESRAM_IN_1_PRIORITY); + + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[0], + b + NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[1], + b + NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[2], + b + NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[0], + b + NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[1], + b + NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[2], + b + NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw2_ddr_in_prio[0], + b + NODE_HIBW2_DDR_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr_in_prio[1], + b + NODE_HIBW2_DDR_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr_in_prio[2], + b + NODE_HIBW2_DDR_IN_2_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr_in_limit[0], + b + NODE_HIBW2_DDR_IN_0_LIMIT); + writel_relaxed(context_icn.hibw2_ddr_in_limit[1], + b + NODE_HIBW2_DDR_IN_1_LIMIT); + writel_relaxed(context_icn.hibw2_ddr_in_limit[2], + b + NODE_HIBW2_DDR_IN_2_LIMIT); + writel_relaxed(context_icn.hibw2_ddr_out_prio, + b + NODE_HIBW2_DDR_OUT_0_PRIORITY); + + writel_relaxed(context_icn.esram0_in_prio[0], + b + NODE_ESRAM0_IN_0_PRIORITY); + writel_relaxed(context_icn.esram0_in_prio[1], + b + NODE_ESRAM0_IN_1_PRIORITY); + writel_relaxed(context_icn.esram0_in_prio[2], + b + NODE_ESRAM0_IN_2_PRIORITY); + writel_relaxed(context_icn.esram0_in_prio[3], + b + NODE_ESRAM0_IN_3_PRIORITY); + + writel_relaxed(context_icn.esram0_in_lim[0], + b + NODE_ESRAM0_IN_0_LIMIT); + writel_relaxed(context_icn.esram0_in_lim[1], + b + NODE_ESRAM0_IN_1_LIMIT); + writel_relaxed(context_icn.esram0_in_lim[2], + b + NODE_ESRAM0_IN_2_LIMIT); + writel_relaxed(context_icn.esram0_in_lim[3], + b + NODE_ESRAM0_IN_3_LIMIT); + + writel_relaxed(context_icn.esram12_in_prio[0], + b + NODE_ESRAM1_2_IN_0_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[1], + b + NODE_ESRAM1_2_IN_1_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[2], + b + NODE_ESRAM1_2_IN_2_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[3], + b + NODE_ESRAM1_2_IN_3_PRIORITY); + + writel_relaxed(context_icn.esram12_in_arb_lim[0], + b + NODE_ESRAM1_2_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[1], + b + NODE_ESRAM1_2_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[2], + b + NODE_ESRAM1_2_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[3], + b + NODE_ESRAM1_2_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[4], + b + NODE_ESRAM1_2_IN_2_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[5], + b + NODE_ESRAM1_2_IN_2_ARB_2_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[6], + b + NODE_ESRAM1_2_IN_3_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[7], + b + NODE_ESRAM1_2_IN_3_ARB_2_LIMIT); + + writel_relaxed(context_icn.esram34_in_prio[0], + b + NODE_ESRAM3_4_IN_0_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[1], + b + NODE_ESRAM3_4_IN_1_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[2], + b + NODE_ESRAM3_4_IN_2_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[3], + b + NODE_ESRAM3_4_IN_3_PRIORITY); + + writel_relaxed(context_icn.esram34_in_arb_lim[0], + b + NODE_ESRAM3_4_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[1], + b + NODE_ESRAM3_4_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[2], + b + NODE_ESRAM3_4_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[3], + b + NODE_ESRAM3_4_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[4], + b + NODE_ESRAM3_4_IN_2_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[5], + b + NODE_ESRAM3_4_IN_2_ARB_2_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[6], + b + NODE_ESRAM3_4_IN_3_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[7], + b + NODE_ESRAM3_4_IN_3_ARB_2_LIMIT); +} + +void u8500_context_init(void) +{ + context_icn.base = ioremap(U8500_ICN_BASE, SZ_8K); +} diff --git a/arch/arm/mach-ux500/pm/context-db9540.c b/arch/arm/mach-ux500/pm/context-db9540.c new file mode 100644 index 00000000000..8d8aaeb9d8f --- /dev/null +++ b/arch/arm/mach-ux500/pm/context-db9540.c @@ -0,0 +1,651 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * License Terms: GNU General Public License v2 + * Author: Sundar Iyer for ST-Ericsson + * + */ + +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/context.h> + +/* + * ST-Interconnect context + */ + +/* priority, bw limiter register offsets */ +#define NODE_HIBW1_ESRAM_IN_0_PRIORITY 0x00 +#define NODE_HIBW1_ESRAM_IN_1_PRIORITY 0x04 +#define NODE_HIBW1_ESRAM_IN_2_PRIORITY 0x08 +#define NODE_HIBW1_ESRAM_IN_3_PRIORITY 0x0C +#define NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT 0x30 +#define NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT 0x34 +#define NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT 0x38 +#define NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT 0x3C +#define NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT 0x40 +#define NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT 0x44 +#define NODE_HIBW1_ESRAM_IN_2_ARB_1_LIMIT 0x48 +#define NODE_HIBW1_ESRAM_IN_2_ARB_2_LIMIT 0x4C +#define NODE_HIBW1_ESRAM_IN_2_ARB_3_LIMIT 0x50 +#define NODE_HIBW1_ESRAM_IN_3_ARB_1_LIMIT 0x54 +#define NODE_HIBW1_ESRAM_IN_3_ARB_2_LIMIT 0x58 +#define NODE_HIBW1_ESRAM_IN_3_ARB_3_LIMIT 0x5C +#define NODE_HIBW1_DDR0_IN_0_PRIORITY 0x400 +#define NODE_HIBW1_DDR0_IN_1_PRIORITY 0x404 +#define NODE_HIBW1_DDR0_IN_2_PRIORITY 0x408 +#define NODE_HIBW1_DDR0_IN_3_PRIORITY 0x40C +#define NODE_HIBW1_DDR0_IN_0_LIMIT 0x430 +#define NODE_HIBW1_DDR0_IN_1_LIMIT 0x434 +#define NODE_HIBW1_DDR0_IN_2_LIMIT 0x438 +#define NODE_HIBW1_DDR0_IN_3_LIMIT 0x43C +#define NODE_HIBW1_DDR0_OUT_0_PRIORITY 0x440 +#define NODE_HIBW2_ESRAM_IN_0_PRIORITY 0x800 +#define NODE_HIBW2_ESRAM_IN_1_PRIORITY 0x804 +#define NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT 0x818 +#define NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT 0x81C +#define NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT 0x820 +#define NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT 0x824 +#define NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT 0x828 +#define NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT 0x82C + +#define NODE_HIBW2_DDR0_IN_0_PRIORITY 0xC00 +#define NODE_HIBW2_DDR0_IN_1_PRIORITY 0xC04 + +#define NODE_HIBW2_DDR0_IN_0_LIMIT 0xC18 +#define NODE_HIBW2_DDR0_IN_1_LIMIT 0xC1C + +#define NODE_HIBW2_DDR0_OUT_0_PRIORITY 0xC20 + +/* + * Note the following addresses are presented in + * db8500 design spec v3.1 and v3.3, table 10. + * But their addresses are not the same as in the + * description. The addresses in the description + * of each registers are correct. + * NODE_HIBW2_DDR_IN_3_LIMIT is only present in v1. + * + * Faulty registers addresses in table 10: + * NODE_HIBW2_DDR_IN_2_LIMIT 0xC38 + * NODE_HIBW2_DDR_IN_3_LIMIT 0xC3C + * NODE_HIBW2_DDR_OUT_0_PRIORITY 0xC40 + */ + +#define NODE_ESRAM0_IN_0_PRIORITY 0x1000 +#define NODE_ESRAM0_IN_1_PRIORITY 0x1004 +#define NODE_ESRAM0_IN_2_PRIORITY 0x1008 +#define NODE_ESRAM0_IN_3_PRIORITY 0x100C +#define NODE_ESRAM0_IN_0_LIMIT 0x1030 +#define NODE_ESRAM0_IN_1_LIMIT 0x1034 +#define NODE_ESRAM0_IN_2_LIMIT 0x1038 +#define NODE_ESRAM0_IN_3_LIMIT 0x103C +#define NODE_ESRAM0_OUT_0_PRIORITY 0x1040 + +/* common */ +#define NODE_ESRAM1_2_IN_0_PRIORITY 0x1400 +#define NODE_ESRAM1_2_IN_1_PRIORITY 0x1404 +#define NODE_ESRAM1_2_IN_2_PRIORITY 0x1408 +#define NODE_ESRAM1_2_IN_3_PRIORITY 0x140C +#define NODE_ESRAM1_2_IN_0_ARB_1_LIMIT 0x1430 +#define NODE_ESRAM1_2_IN_0_ARB_2_LIMIT 0x1434 +#define NODE_ESRAM1_2_IN_1_ARB_1_LIMIT 0x1438 +#define NODE_ESRAM1_2_IN_1_ARB_2_LIMIT 0x143C +#define NODE_ESRAM1_2_IN_2_ARB_1_LIMIT 0x1440 +#define NODE_ESRAM1_2_IN_2_ARB_2_LIMIT 0x1444 +#define NODE_ESRAM1_2_IN_3_ARB_1_LIMIT 0x1448 +#define NODE_ESRAM1_2_IN_3_ARB_2_LIMIT 0x144C + +#define NODE_ESRAM3_4_IN_0_PRIORITY 0x1800 +#define NODE_ESRAM3_4_IN_1_PRIORITY 0x1804 +#define NODE_ESRAM3_4_IN_2_PRIORITY 0x1808 +#define NODE_ESRAM3_4_IN_3_PRIORITY 0x180C +#define NODE_ESRAM3_4_IN_0_ARB_1_LIMIT 0x1830 +#define NODE_ESRAM3_4_IN_0_ARB_2_LIMIT 0x1834 +#define NODE_ESRAM3_4_IN_1_ARB_1_LIMIT 0x1838 +#define NODE_ESRAM3_4_IN_1_ARB_2_LIMIT 0x183C +#define NODE_ESRAM3_4_IN_2_ARB_1_LIMIT 0x1840 +#define NODE_ESRAM3_4_IN_2_ARB_2_LIMIT 0x1844 +#define NODE_ESRAM3_4_IN_3_ARB_1_LIMIT 0x1848 +#define NODE_ESRAM3_4_IN_3_ARB_2_LIMIT 0x184C + +#define NODE_HIBW1_DDR1_IN_0_PRIORITY_REG 0x1C00 +#define NODE_HIBW1_DDR1_IN_1_PRIORITY_REG 0x1C04 +#define NODE_HIBW1_DDR1_IN_2_PRIORITY_REG 0x1C08 +#define NODE_HIBW1_DDR1_IN_3_PRIORITY_REG 0x1C0C + +#define NODE_HIBW1_DDR1_IN_0_LIMIT_REG 0x1C30 +#define NODE_HIBW1_DDR1_IN_1_LIMIT_REG 0x1C34 +#define NODE_HIBW1_DDR1_IN_2_LIMIT_REG 0x1C38 +#define NODE_HIBW1_DDR1_IN_3_LIMIT_REG 0x1C3C + +#define NODE_HIBW1_DDR1_OUT_0_PRIORITY_REG 0x1C40 + +#define NODE_HIBW2_DDR1_IN_0_PRIORITY_REG 0x2000 +#define NODE_HIBW2_DDR1_IN_1_PRIORITY_REG 0x2004 + +#define NODE_HIBW2_DDR1_IN_0_LIMIT_REG 0x2018 +#define NODE_HIBW2_DDR1_IN_1_LIMIT_REG 0x201C +#define NODE_HIBW2_DDR1_OUT_0_PRIORITY_REG 0x2020 +#define NODE_DDR_AWQOS_DSP_DDR0_REG 0x340C +#define NODE_DDR_AWQOS_DSP_DDR1_REG 0x3400 +#define NODE_DDR_ARQOS_DSP_DDR0_REG 0x3408 +#define NODE_DDR_ARQOS_DSP_DDR1_REG 0x3404 +#define NODE_DDR_AWQOS_ARM_DDR_REG 0x3410 +#define NODE_DDR_ARQOS_ARM_DDR_REG 0x3414 +#define NODE_SGA_AWQOS_DDR0_HIBW2_REG 0x3418 +#define NODE_SGA_ARQOS_DDR0_HIBW2_REG 0x341C +#define NODE_SGA_AWQOS_SGA_HIBW2_REG 0x3420 +#define NODE_SGA_ARQOS_SGA_HIBW2_REG 0x3424 + +static struct { + void __iomem *base; + u32 hibw1_esram_in_pri[4]; + u32 hibw1_esram_in0_arb[3]; + u32 hibw1_esram_in1_arb[3]; + u32 hibw1_esram_in2_arb[3]; + u32 hibw1_esram_in3_arb[3]; + u32 hibw1_ddr0_in_prio[4]; + u32 hibw1_ddr0_in_limit[4]; + u32 hibw1_ddr0_out_prio; + u32 hibw1_ddr1_in_prio[4]; + u32 hibw1_ddr1_in_limit[4]; + u32 hibw1_ddr1_out_prio; + + /* HiBw2 node registers */ + u32 hibw2_esram_in_pri[2]; + u32 hibw2_esram_in0_arblimit[3]; + u32 hibw2_esram_in1_arblimit[3]; + u32 hibw2_ddr0_in_prio[2]; + u32 hibw2_ddr0_in_limit[2]; + u32 hibw2_ddr0_out_prio; + u32 hibw2_ddr1_in_prio[2]; + u32 hibw2_ddr1_in_limit[2]; + u32 hibw2_ddr1_out_prio; + + /* ESRAM node registers */ + u32 esram0_in_prio[4]; + u32 esram0_in_lim[4]; + u32 esram0_out_prio; + u32 esram12_in_prio[4]; + u32 esram12_in_arb_lim[8]; + u32 esram34_in_prio[4]; + u32 esram34_in_arb_lim[8]; + + u32 ddr_awqos_dsp_ddr0; + u32 ddr_awqos_dsp_ddr1; + u32 ddr_arqos_dsp_ddr0; + u32 ddr_arqos_dsp_ddr1; + u32 ddr_awqos_arm_ddr; + u32 ddr_arqos_arm_ddr; + + u32 sga_awqos_ddr0_hibw2; + u32 sga_arqos_ddr0_hibw2; + + u32 sga_awqos_sga_hibw2; + u32 sga_arqos_sga_hibw2; +} context_icn; + +/** + * u8500_context_save_icn() - save ICN context + * + */ +void u9540_context_save_icn(void) +{ + void __iomem *b = context_icn.base; + + context_icn.hibw1_esram_in_pri[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_PRIORITY); + context_icn.hibw1_esram_in_pri[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_PRIORITY); + context_icn.hibw1_esram_in_pri[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_PRIORITY); + context_icn.hibw1_esram_in_pri[3] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_3_PRIORITY); + + context_icn.hibw1_esram_in0_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT); + context_icn.hibw1_esram_in0_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT); + context_icn.hibw1_esram_in0_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT); + + context_icn.hibw1_esram_in1_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT); + context_icn.hibw1_esram_in1_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT); + context_icn.hibw1_esram_in1_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT); + + context_icn.hibw1_esram_in2_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_ARB_1_LIMIT); + context_icn.hibw1_esram_in2_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_ARB_2_LIMIT); + context_icn.hibw1_esram_in2_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_2_ARB_3_LIMIT); + + context_icn.hibw1_esram_in3_arb[0] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_3_ARB_1_LIMIT); + context_icn.hibw1_esram_in3_arb[1] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_3_ARB_2_LIMIT); + context_icn.hibw1_esram_in3_arb[2] = + readl_relaxed(b + NODE_HIBW1_ESRAM_IN_3_ARB_3_LIMIT); + + context_icn.hibw1_ddr0_in_prio[0] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_0_PRIORITY); + context_icn.hibw1_ddr0_in_prio[1] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_1_PRIORITY); + context_icn.hibw1_ddr0_in_prio[2] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_2_PRIORITY); + context_icn.hibw1_ddr0_in_prio[3] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_3_PRIORITY); + + context_icn.hibw1_ddr0_in_limit[0] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_0_LIMIT); + context_icn.hibw1_ddr0_in_limit[1] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_1_LIMIT); + context_icn.hibw1_ddr0_in_limit[2] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_2_LIMIT); + context_icn.hibw1_ddr0_in_limit[3] = + readl_relaxed(b + NODE_HIBW1_DDR0_IN_3_LIMIT); + + context_icn.hibw1_ddr0_out_prio = + readl_relaxed(b + NODE_HIBW1_DDR0_OUT_0_PRIORITY); + + context_icn.hibw1_ddr1_in_prio[0] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_0_PRIORITY_REG); + context_icn.hibw1_ddr1_in_prio[1] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_1_PRIORITY_REG); + context_icn.hibw1_ddr1_in_prio[2] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_2_PRIORITY_REG); + context_icn.hibw1_ddr1_in_prio[3] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_3_PRIORITY_REG); + + context_icn.hibw1_ddr1_in_limit[0] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_0_LIMIT_REG); + context_icn.hibw1_ddr1_in_limit[1] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_1_LIMIT_REG); + context_icn.hibw1_ddr1_in_limit[2] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_2_LIMIT_REG); + context_icn.hibw1_ddr1_in_limit[3] = + readl_relaxed(b + NODE_HIBW1_DDR1_IN_3_LIMIT_REG); + + context_icn.hibw1_ddr1_out_prio = + readl_relaxed(b + NODE_HIBW1_DDR1_OUT_0_PRIORITY_REG); + + context_icn.hibw2_esram_in_pri[0] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_PRIORITY); + context_icn.hibw2_esram_in_pri[1] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_PRIORITY); + + context_icn.hibw2_esram_in0_arblimit[0] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT); + context_icn.hibw2_esram_in0_arblimit[1] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT); + context_icn.hibw2_esram_in0_arblimit[2] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT); + + context_icn.hibw2_esram_in1_arblimit[0] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT); + context_icn.hibw2_esram_in1_arblimit[1] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT); + context_icn.hibw2_esram_in1_arblimit[2] = + readl_relaxed(b + NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT); + + context_icn.hibw2_ddr0_in_prio[0] = + readl_relaxed(b + NODE_HIBW2_DDR0_IN_0_PRIORITY); + context_icn.hibw2_ddr0_in_prio[1] = + readl_relaxed(b + NODE_HIBW2_DDR0_IN_1_PRIORITY); + + context_icn.hibw2_ddr0_in_limit[0] = + readl_relaxed(b + NODE_HIBW2_DDR0_IN_0_LIMIT); + context_icn.hibw2_ddr0_in_limit[1] = + readl_relaxed(b + NODE_HIBW2_DDR0_IN_1_LIMIT); + + context_icn.hibw2_ddr0_out_prio = + readl_relaxed(b + NODE_HIBW2_DDR0_OUT_0_PRIORITY); + + context_icn.hibw2_ddr1_in_prio[0] = + readl_relaxed(b + NODE_HIBW2_DDR1_IN_0_PRIORITY_REG); + context_icn.hibw2_ddr1_in_prio[1] = + readl_relaxed(b + NODE_HIBW2_DDR1_IN_1_PRIORITY_REG); + + context_icn.hibw2_ddr1_in_limit[0] = + readl_relaxed(b + NODE_HIBW2_DDR1_IN_0_LIMIT_REG); + context_icn.hibw2_ddr1_in_limit[1] = + readl_relaxed(b + NODE_HIBW2_DDR1_IN_1_LIMIT_REG); + + context_icn.hibw2_ddr1_out_prio = + readl_relaxed(b + NODE_HIBW2_DDR1_OUT_0_PRIORITY_REG); + + context_icn.esram0_in_prio[0] = + readl_relaxed(b + NODE_ESRAM0_IN_0_PRIORITY); + context_icn.esram0_in_prio[1] = + readl_relaxed(b + NODE_ESRAM0_IN_1_PRIORITY); + context_icn.esram0_in_prio[2] = + readl_relaxed(b + NODE_ESRAM0_IN_2_PRIORITY); + context_icn.esram0_in_prio[3] = + readl_relaxed(b + NODE_ESRAM0_IN_3_PRIORITY); + + context_icn.esram0_in_lim[0] = + readl_relaxed(b + NODE_ESRAM0_IN_0_LIMIT); + context_icn.esram0_in_lim[1] = + readl_relaxed(b + NODE_ESRAM0_IN_1_LIMIT); + context_icn.esram0_in_lim[2] = + readl_relaxed(b + NODE_ESRAM0_IN_2_LIMIT); + context_icn.esram0_in_lim[3] = + readl_relaxed(b + NODE_ESRAM0_IN_3_LIMIT); + + context_icn.esram0_out_prio = + readl_relaxed(b + NODE_ESRAM0_OUT_0_PRIORITY); + + context_icn.esram12_in_prio[0] = + readl_relaxed(b + NODE_ESRAM1_2_IN_0_PRIORITY); + context_icn.esram12_in_prio[1] = + readl_relaxed(b + NODE_ESRAM1_2_IN_1_PRIORITY); + context_icn.esram12_in_prio[2] = + readl_relaxed(b + NODE_ESRAM1_2_IN_2_PRIORITY); + context_icn.esram12_in_prio[3] = + readl_relaxed(b + NODE_ESRAM1_2_IN_3_PRIORITY); + + context_icn.esram12_in_arb_lim[0] = + readl_relaxed(b + NODE_ESRAM1_2_IN_0_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[1] = + readl_relaxed(b + NODE_ESRAM1_2_IN_0_ARB_2_LIMIT); + context_icn.esram12_in_arb_lim[2] = + readl_relaxed(b + NODE_ESRAM1_2_IN_1_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[3] = + readl_relaxed(b + NODE_ESRAM1_2_IN_1_ARB_2_LIMIT); + context_icn.esram12_in_arb_lim[4] = + readl_relaxed(b + NODE_ESRAM1_2_IN_2_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[5] = + readl_relaxed(b + NODE_ESRAM1_2_IN_2_ARB_2_LIMIT); + context_icn.esram12_in_arb_lim[6] = + readl_relaxed(b + NODE_ESRAM1_2_IN_3_ARB_1_LIMIT); + context_icn.esram12_in_arb_lim[7] = + readl_relaxed(b + NODE_ESRAM1_2_IN_3_ARB_2_LIMIT); + + context_icn.esram34_in_prio[0] = + readl_relaxed(b + NODE_ESRAM3_4_IN_0_PRIORITY); + context_icn.esram34_in_prio[1] = + readl_relaxed(b + NODE_ESRAM3_4_IN_1_PRIORITY); + context_icn.esram34_in_prio[2] = + readl_relaxed(b + NODE_ESRAM3_4_IN_2_PRIORITY); + context_icn.esram34_in_prio[3] = + readl_relaxed(b + NODE_ESRAM3_4_IN_3_PRIORITY); + + context_icn.esram34_in_arb_lim[0] = + readl_relaxed(b + NODE_ESRAM3_4_IN_0_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[1] = + readl_relaxed(b + NODE_ESRAM3_4_IN_0_ARB_2_LIMIT); + context_icn.esram34_in_arb_lim[2] = + readl_relaxed(b + NODE_ESRAM3_4_IN_1_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[3] = + readl_relaxed(b + NODE_ESRAM3_4_IN_1_ARB_2_LIMIT); + context_icn.esram34_in_arb_lim[4] = + readl_relaxed(b + NODE_ESRAM3_4_IN_2_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[5] = + readl_relaxed(b + NODE_ESRAM3_4_IN_2_ARB_2_LIMIT); + context_icn.esram34_in_arb_lim[6] = + readl_relaxed(b + NODE_ESRAM3_4_IN_3_ARB_1_LIMIT); + context_icn.esram34_in_arb_lim[7] = + readl_relaxed(b + NODE_ESRAM3_4_IN_3_ARB_2_LIMIT); + + context_icn.ddr_awqos_dsp_ddr0 = + readl_relaxed(b + NODE_DDR_AWQOS_DSP_DDR0_REG); + context_icn.ddr_awqos_dsp_ddr1 = + readl_relaxed(b + NODE_DDR_AWQOS_DSP_DDR1_REG); + context_icn.ddr_arqos_dsp_ddr0 = + readl_relaxed(b + NODE_DDR_ARQOS_DSP_DDR0_REG); + context_icn.ddr_arqos_dsp_ddr1 = + readl_relaxed(b + NODE_DDR_ARQOS_DSP_DDR1_REG); + context_icn.ddr_awqos_arm_ddr = + readl_relaxed(b + NODE_DDR_AWQOS_ARM_DDR_REG); + context_icn.ddr_arqos_arm_ddr = + readl_relaxed(b + NODE_DDR_ARQOS_ARM_DDR_REG); + + context_icn.sga_awqos_ddr0_hibw2 = + readl_relaxed(b + NODE_SGA_AWQOS_DDR0_HIBW2_REG); + context_icn.sga_arqos_ddr0_hibw2 = + readl_relaxed(b + NODE_SGA_ARQOS_DDR0_HIBW2_REG); + + context_icn.sga_awqos_sga_hibw2 = + readl_relaxed(b + NODE_SGA_AWQOS_SGA_HIBW2_REG); + context_icn.sga_arqos_sga_hibw2 = + readl_relaxed(b + NODE_SGA_ARQOS_SGA_HIBW2_REG); +} + +/** + * u9540_context_restore_icn() - restore ICN context + * + */ +void u9540_context_restore_icn(void) +{ + void __iomem *b = context_icn.base; + + writel_relaxed(context_icn.hibw1_esram_in_pri[0], + b + NODE_HIBW1_ESRAM_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw1_esram_in_pri[1], + b + NODE_HIBW1_ESRAM_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw1_esram_in_pri[2], + b + NODE_HIBW1_ESRAM_IN_2_PRIORITY); + writel_relaxed(context_icn.hibw1_esram_in_pri[3], + b + NODE_HIBW1_ESRAM_IN_3_PRIORITY); + + writel_relaxed(context_icn.hibw1_esram_in0_arb[0], + b + NODE_HIBW1_ESRAM_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in0_arb[1], + b + NODE_HIBW1_ESRAM_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in0_arb[2], + b + NODE_HIBW1_ESRAM_IN_0_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_esram_in1_arb[0], + b + NODE_HIBW1_ESRAM_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in1_arb[1], + b + NODE_HIBW1_ESRAM_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in1_arb[2], + b + NODE_HIBW1_ESRAM_IN_1_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_esram_in2_arb[0], + b + NODE_HIBW1_ESRAM_IN_2_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in2_arb[1], + b + NODE_HIBW1_ESRAM_IN_2_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in2_arb[2], + b + NODE_HIBW1_ESRAM_IN_2_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_esram_in3_arb[0], + b + NODE_HIBW1_ESRAM_IN_3_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in3_arb[1], + b + NODE_HIBW1_ESRAM_IN_3_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw1_esram_in3_arb[2], + b + NODE_HIBW1_ESRAM_IN_3_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw1_ddr0_in_prio[0], + b + NODE_HIBW1_DDR0_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr0_in_prio[1], + b + NODE_HIBW1_DDR0_IN_1_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr0_in_prio[2], + b + NODE_HIBW1_DDR0_IN_2_PRIORITY); + writel_relaxed(context_icn.hibw1_ddr0_in_prio[3], + b + NODE_HIBW1_DDR0_IN_3_PRIORITY); + + writel_relaxed(context_icn.hibw1_ddr0_in_limit[0], + b + NODE_HIBW1_DDR0_IN_0_LIMIT); + writel_relaxed(context_icn.hibw1_ddr0_in_limit[1], + b + NODE_HIBW1_DDR0_IN_1_LIMIT); + writel_relaxed(context_icn.hibw1_ddr0_in_limit[2], + b + NODE_HIBW1_DDR0_IN_2_LIMIT); + writel_relaxed(context_icn.hibw1_ddr0_in_limit[3], + b + NODE_HIBW1_DDR0_IN_3_LIMIT); + + writel_relaxed(context_icn.hibw1_ddr0_out_prio, + b + NODE_HIBW1_DDR0_OUT_0_PRIORITY); + + writel_relaxed(context_icn.hibw1_ddr1_in_prio[0], + b + NODE_HIBW1_DDR1_IN_0_PRIORITY_REG); + writel_relaxed(context_icn.hibw1_ddr1_in_prio[1], + b + NODE_HIBW1_DDR1_IN_1_PRIORITY_REG); + writel_relaxed(context_icn.hibw1_ddr1_in_prio[2], + b + NODE_HIBW1_DDR1_IN_2_PRIORITY_REG); + writel_relaxed(context_icn.hibw1_ddr1_in_prio[3], + b + NODE_HIBW1_DDR1_IN_3_PRIORITY_REG); + + writel_relaxed(context_icn.hibw1_ddr1_in_limit[0], + b + NODE_HIBW1_DDR1_IN_0_LIMIT_REG); + writel_relaxed(context_icn.hibw1_ddr1_in_limit[1], + b + NODE_HIBW1_DDR1_IN_1_LIMIT_REG); + writel_relaxed(context_icn.hibw1_ddr1_in_limit[2], + b + NODE_HIBW1_DDR1_IN_2_LIMIT_REG); + writel_relaxed(context_icn.hibw1_ddr1_in_limit[3], + b + NODE_HIBW1_DDR1_IN_3_LIMIT_REG); + + writel_relaxed(context_icn.hibw1_ddr1_out_prio, + b + NODE_HIBW1_DDR1_OUT_0_PRIORITY_REG); + + writel_relaxed(context_icn.hibw2_esram_in_pri[0], + b + NODE_HIBW2_ESRAM_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw2_esram_in_pri[1], + b + NODE_HIBW2_ESRAM_IN_1_PRIORITY); + + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[0], + b + NODE_HIBW2_ESRAM_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[1], + b + NODE_HIBW2_ESRAM_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in0_arblimit[2], + b + NODE_HIBW2_ESRAM_IN_0_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[0], + b + NODE_HIBW2_ESRAM_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[1], + b + NODE_HIBW2_ESRAM_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.hibw2_esram_in1_arblimit[2], + b + NODE_HIBW2_ESRAM_IN_1_ARB_3_LIMIT); + + writel_relaxed(context_icn.hibw2_ddr0_in_prio[0], + b + NODE_HIBW2_DDR0_IN_0_PRIORITY); + writel_relaxed(context_icn.hibw2_ddr0_in_prio[1], + b + NODE_HIBW2_DDR0_IN_1_PRIORITY); + + writel_relaxed(context_icn.hibw2_ddr0_in_limit[0], + b + NODE_HIBW2_DDR0_IN_0_LIMIT); + writel_relaxed(context_icn.hibw2_ddr0_in_limit[1], + b + NODE_HIBW2_DDR0_IN_1_LIMIT); + + writel_relaxed(context_icn.hibw2_ddr0_out_prio, + b + NODE_HIBW2_DDR0_OUT_0_PRIORITY); + + writel_relaxed(context_icn.hibw2_ddr1_in_prio[0], + b + NODE_HIBW2_DDR1_IN_0_PRIORITY_REG); + writel_relaxed(context_icn.hibw2_ddr1_in_prio[1], + b + NODE_HIBW2_DDR1_IN_1_PRIORITY_REG); + + writel_relaxed(context_icn.hibw2_ddr1_in_limit[0], + b + NODE_HIBW2_DDR1_IN_0_LIMIT_REG); + writel_relaxed(context_icn.hibw2_ddr1_in_limit[1], + b + NODE_HIBW2_DDR1_IN_1_LIMIT_REG); + + writel_relaxed(context_icn.hibw2_ddr1_out_prio, + b + NODE_HIBW2_DDR1_OUT_0_PRIORITY_REG); + + writel_relaxed(context_icn.esram0_in_prio[0], + b + NODE_ESRAM0_IN_0_PRIORITY); + writel_relaxed(context_icn.esram0_in_prio[1], + b + NODE_ESRAM0_IN_1_PRIORITY); + writel_relaxed(context_icn.esram0_in_prio[2], + b + NODE_ESRAM0_IN_2_PRIORITY); + writel_relaxed(context_icn.esram0_in_prio[3], + b + NODE_ESRAM0_IN_3_PRIORITY); + + writel_relaxed(context_icn.esram0_in_lim[0], + b + NODE_ESRAM0_IN_0_LIMIT); + writel_relaxed(context_icn.esram0_in_lim[1], + b + NODE_ESRAM0_IN_1_LIMIT); + writel_relaxed(context_icn.esram0_in_lim[2], + b + NODE_ESRAM0_IN_2_LIMIT); + writel_relaxed(context_icn.esram0_in_lim[3], + b + NODE_ESRAM0_IN_3_LIMIT); + + writel_relaxed(context_icn.esram0_out_prio, + b + NODE_ESRAM0_OUT_0_PRIORITY); + + writel_relaxed(context_icn.esram12_in_prio[0], + b + NODE_ESRAM1_2_IN_0_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[1], + b + NODE_ESRAM1_2_IN_1_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[2], + b + NODE_ESRAM1_2_IN_2_PRIORITY); + writel_relaxed(context_icn.esram12_in_prio[3], + b + NODE_ESRAM1_2_IN_3_PRIORITY); + + writel_relaxed(context_icn.esram12_in_arb_lim[0], + b + NODE_ESRAM1_2_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[1], + b + NODE_ESRAM1_2_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[2], + b + NODE_ESRAM1_2_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[3], + b + NODE_ESRAM1_2_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[4], + b + NODE_ESRAM1_2_IN_2_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[5], + b + NODE_ESRAM1_2_IN_2_ARB_2_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[6], + b + NODE_ESRAM1_2_IN_3_ARB_1_LIMIT); + writel_relaxed(context_icn.esram12_in_arb_lim[7], + b + NODE_ESRAM1_2_IN_3_ARB_2_LIMIT); + + writel_relaxed(context_icn.esram34_in_prio[0], + b + NODE_ESRAM3_4_IN_0_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[1], + b + NODE_ESRAM3_4_IN_1_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[2], + b + NODE_ESRAM3_4_IN_2_PRIORITY); + writel_relaxed(context_icn.esram34_in_prio[3], + b + NODE_ESRAM3_4_IN_3_PRIORITY); + + writel_relaxed(context_icn.esram34_in_arb_lim[0], + b + NODE_ESRAM3_4_IN_0_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[1], + b + NODE_ESRAM3_4_IN_0_ARB_2_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[2], + b + NODE_ESRAM3_4_IN_1_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[3], + b + NODE_ESRAM3_4_IN_1_ARB_2_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[4], + b + NODE_ESRAM3_4_IN_2_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[5], + b + NODE_ESRAM3_4_IN_2_ARB_2_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[6], + b + NODE_ESRAM3_4_IN_3_ARB_1_LIMIT); + writel_relaxed(context_icn.esram34_in_arb_lim[7], + b + NODE_ESRAM3_4_IN_3_ARB_2_LIMIT); + + writel_relaxed(context_icn.ddr_awqos_dsp_ddr0, + b + NODE_DDR_AWQOS_DSP_DDR0_REG); + writel_relaxed(context_icn.ddr_awqos_dsp_ddr1, + b + NODE_DDR_AWQOS_DSP_DDR1_REG); + writel_relaxed(context_icn.ddr_arqos_dsp_ddr0, + b + NODE_DDR_ARQOS_DSP_DDR0_REG); + writel_relaxed(context_icn.ddr_arqos_dsp_ddr1, + b + NODE_DDR_ARQOS_DSP_DDR1_REG); + writel_relaxed(context_icn.ddr_awqos_arm_ddr, + b + NODE_DDR_AWQOS_ARM_DDR_REG); + writel_relaxed(context_icn.ddr_arqos_arm_ddr, + b + NODE_DDR_ARQOS_ARM_DDR_REG); + + writel_relaxed(context_icn.sga_awqos_ddr0_hibw2, + b + NODE_SGA_AWQOS_DDR0_HIBW2_REG); + writel_relaxed(context_icn.sga_arqos_ddr0_hibw2, + b + NODE_SGA_ARQOS_DDR0_HIBW2_REG); + + writel_relaxed(context_icn.sga_awqos_sga_hibw2, + b + NODE_SGA_AWQOS_SGA_HIBW2_REG); + writel_relaxed(context_icn.sga_arqos_sga_hibw2, + b + NODE_SGA_ARQOS_SGA_HIBW2_REG); +} + +void u9540_context_init(void) +{ + context_icn.base = ioremap(U8500_ICN_BASE, SZ_16K); +} diff --git a/arch/arm/mach-ux500/pm/context.c b/arch/arm/mach-ux500/pm/context.c new file mode 100644 index 00000000000..5902b861930 --- /dev/null +++ b/arch/arm/mach-ux500/pm/context.c @@ -0,0 +1,1002 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2011 + * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com>, + * Rickard Andersson <rickard.andersson@stericsson.com>, + * Jonas Aaberg <jonas.aberg@stericsson.com>, + * Sundar Iyer for ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2 + * + */ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/io.h> +#include <linux/smp.h> +#include <linux/percpu.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/device.h> +#include <linux/notifier.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/gpio/nomadik.h> + +#include <mach/hardware.h> +#include <mach/irqs.h> +#include <mach/pm.h> +#include <mach/context.h> + +#include <asm/hardware/gic.h> +#include <asm/smp_twd.h> + +#include "scu.h" +#include "../product.h" +#include "../prcc.h" + +#include "../board-pins-sleep-force.h" + +#define GPIO_NUM_BANKS 9 +#define GPIO_NUM_SAVE_REGISTERS 7 + +/* + * TODO: + * - Use the "UX500*"-macros instead where possible + */ + +#define U8500_BACKUPRAM_SIZE SZ_64K + +#define U8500_PUBLIC_BOOT_ROM_BASE (U8500_BOOT_ROM_BASE + 0x17000) +#define U9540_PUBLIC_BOOT_ROM_BASE (U9540_BOOT_ROM_BASE + 0x17000) +#define U5500_PUBLIC_BOOT_ROM_BASE (U5500_BOOT_ROM_BASE + 0x18000) + +/* + * Special dedicated addresses in backup RAM. The 5500 addresses are identical + * to the 8500 ones. + */ +#define U8500_EXT_RAM_LOC_BACKUPRAM_ADDR 0x80151FDC +#define U8500_CPU0_CP15_CR_BACKUPRAM_ADDR 0x80151F80 +#define U8500_CPU1_CP15_CR_BACKUPRAM_ADDR 0x80151FA0 + +#define U8500_CPU0_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR 0x80151FD8 +#define U8500_CPU1_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR 0x80151FE0 + +#define GIC_DIST_ENABLE_NS 0x0 + +/* 32 interrupts fits in 4 bytes */ +#define GIC_DIST_ENABLE_SET_COMMON_NUM ((DBX500_NR_INTERNAL_IRQS - \ + IRQ_SHPI_START) / 32) +#define GIC_DIST_ENABLE_SET_CPU_NUM (IRQ_SHPI_START / 32) +#define GIC_DIST_ENABLE_SET_SPI0 GIC_DIST_ENABLE_SET +#define GIC_DIST_ENABLE_SET_SPI32 (GIC_DIST_ENABLE_SET + IRQ_SHPI_START / 8) + +#define GIC_DIST_ENABLE_CLEAR_0 GIC_DIST_ENABLE_CLEAR +#define GIC_DIST_ENABLE_CLEAR_32 (GIC_DIST_ENABLE_CLEAR + 4) +#define GIC_DIST_ENABLE_CLEAR_64 (GIC_DIST_ENABLE_CLEAR + 8) +#define GIC_DIST_ENABLE_CLEAR_96 (GIC_DIST_ENABLE_CLEAR + 12) +#define GIC_DIST_ENABLE_CLEAR_128 (GIC_DIST_ENABLE_CLEAR + 16) + +#define GIC_DIST_PRI_COMMON_NUM ((DBX500_NR_INTERNAL_IRQS - IRQ_SHPI_START) / 4) +#define GIC_DIST_PRI_CPU_NUM (IRQ_SHPI_START / 4) +#define GIC_DIST_PRI_SPI0 GIC_DIST_PRI +#define GIC_DIST_PRI_SPI32 (GIC_DIST_PRI + IRQ_SHPI_START) + +#define GIC_DIST_SPI_TARGET_COMMON_NUM ((DBX500_NR_INTERNAL_IRQS - \ + IRQ_SHPI_START) / 4) +#define GIC_DIST_SPI_TARGET_CPU_NUM (IRQ_SHPI_START / 4) +#define GIC_DIST_SPI_TARGET_SPI0 GIC_DIST_TARGET +#define GIC_DIST_SPI_TARGET_SPI32 (GIC_DIST_TARGET + IRQ_SHPI_START) + +/* 16 interrupts per 4 bytes */ +#define GIC_DIST_CONFIG_COMMON_NUM ((DBX500_NR_INTERNAL_IRQS - IRQ_SHPI_START) \ + / 16) +#define GIC_DIST_CONFIG_CPU_NUM (IRQ_SHPI_START / 16) +#define GIC_DIST_CONFIG_SPI0 GIC_DIST_CONFIG +#define GIC_DIST_CONFIG_SPI32 (GIC_DIST_CONFIG + IRQ_SHPI_START / 4) + +/* TODO! Move STM reg offsets to suitable place */ +#define STM_CR_OFFSET 0x00 +#define STM_MMC_OFFSET 0x08 +#define STM_TER_OFFSET 0x10 + +#define TPIU_PORT_SIZE 0x4 +#define TPIU_TRIGGER_COUNTER 0x104 +#define TPIU_TRIGGER_MULTIPLIER 0x108 +#define TPIU_CURRENT_TEST_PATTERN 0x204 +#define TPIU_TEST_PATTERN_REPEAT 0x208 +#define TPIU_FORMATTER 0x304 +#define TPIU_FORMATTER_SYNC 0x308 +#define TPIU_LOCK_ACCESS_REGISTER 0xFB0 + +#define TPIU_UNLOCK_CODE 0xc5acce55 + +#define SCU_FILTER_STARTADDR 0x40 +#define SCU_FILTER_ENDADDR 0x44 +#define SCU_ACCESS_CTRL_SAC 0x50 + +/* The context of the Trace Port Interface Unit (TPIU) */ +static struct { + void __iomem *base; + u32 port_size; + u32 trigger_counter; + u32 trigger_multiplier; + u32 current_test_pattern; + u32 test_pattern_repeat; + u32 formatter; + u32 formatter_sync; +} context_tpiu; + +static struct { + void __iomem *base; + u32 cr; + u32 mmc; + u32 ter; +} context_stm_ape; + +struct context_gic_cpu { + void __iomem *base; + u32 ctrl; + u32 primask; + u32 binpoint; +}; +static DEFINE_PER_CPU(struct context_gic_cpu, context_gic_cpu); + +static struct { + void __iomem *base; + u32 ns; + u32 enable_set[GIC_DIST_ENABLE_SET_COMMON_NUM]; /* IRQ 32 to 160 */ + u32 priority_level[GIC_DIST_PRI_COMMON_NUM]; + u32 spi_target[GIC_DIST_SPI_TARGET_COMMON_NUM]; + u32 config[GIC_DIST_CONFIG_COMMON_NUM]; +} context_gic_dist_common; + +struct context_gic_dist_cpu { + void __iomem *base; + u32 enable_set[GIC_DIST_ENABLE_SET_CPU_NUM]; /* IRQ 0 to 31 */ + u32 priority_level[GIC_DIST_PRI_CPU_NUM]; + u32 spi_target[GIC_DIST_SPI_TARGET_CPU_NUM]; + u32 config[GIC_DIST_CONFIG_CPU_NUM]; +}; +static DEFINE_PER_CPU(struct context_gic_dist_cpu, context_gic_dist_cpu); + +static struct { + void __iomem *base; + u32 ctrl; + u32 cpu_pwrstatus; + u32 inv_all_nonsecure; + u32 filter_start_addr; + u32 filter_end_addr; + u32 access_ctrl_sac; +} context_scu; + +#define UX500_NR_PRCC_BANKS 5 +static struct { + void __iomem *base; + struct clk *clk; + u32 bus_clk; + u32 kern_clk; +} context_prcc[UX500_NR_PRCC_BANKS]; + +static u32 backup_sram_storage[NR_CPUS] = { + IO_ADDRESS(U8500_CPU0_CP15_CR_BACKUPRAM_ADDR), + IO_ADDRESS(U8500_CPU1_CP15_CR_BACKUPRAM_ADDR), +}; + +static u32 gpio_bankaddr[GPIO_NUM_BANKS] = {IO_ADDRESS(U8500_GPIOBANK0_BASE), + IO_ADDRESS(U8500_GPIOBANK1_BASE), + IO_ADDRESS(U8500_GPIOBANK2_BASE), + IO_ADDRESS(U8500_GPIOBANK3_BASE), + IO_ADDRESS(U8500_GPIOBANK4_BASE), + IO_ADDRESS(U8500_GPIOBANK5_BASE), + IO_ADDRESS(U8500_GPIOBANK6_BASE), + IO_ADDRESS(U8500_GPIOBANK7_BASE), + IO_ADDRESS(U8500_GPIOBANK8_BASE) +}; + +static u32 gpio_save[GPIO_NUM_BANKS][GPIO_NUM_SAVE_REGISTERS]; + +void __iomem *fsmc_base_addr; +static u32 fsmc_bcr0; +/* + * Stacks and stack pointers + */ +static DEFINE_PER_CPU(u32[128], varm_registers_backup_stack); +static DEFINE_PER_CPU(u32 *, varm_registers_pointer); + +static DEFINE_PER_CPU(u32[128], varm_cp15_backup_stack); +static DEFINE_PER_CPU(u32 *, varm_cp15_pointer); + +static ATOMIC_NOTIFIER_HEAD(context_ape_notifier_list); +static ATOMIC_NOTIFIER_HEAD(context_arm_notifier_list); + +/* + * Register a simple callback for handling vape context save/restore + */ +int context_ape_notifier_register(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&context_ape_notifier_list, nb); +} +EXPORT_SYMBOL(context_ape_notifier_register); + +/* + * Remove a previously registered callback + */ +int context_ape_notifier_unregister(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&context_ape_notifier_list, + nb); +} +EXPORT_SYMBOL(context_ape_notifier_unregister); + +/* + * Register a simple callback for handling varm context save/restore + */ +int context_arm_notifier_register(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&context_arm_notifier_list, nb); +} +EXPORT_SYMBOL(context_arm_notifier_register); + +/* + * Remove a previously registered callback + */ +int context_arm_notifier_unregister(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&context_arm_notifier_list, + nb); +} +EXPORT_SYMBOL(context_arm_notifier_unregister); + +static void save_prcc(void) +{ + int i; + + for (i = 0; i < UX500_NR_PRCC_BANKS; i++) { + clk_enable(context_prcc[i].clk); + + context_prcc[i].bus_clk = + readl(context_prcc[i].base + PRCC_PCKSR); + context_prcc[i].kern_clk = + readl(context_prcc[i].base + PRCC_KCKSR); + + clk_disable(context_prcc[i].clk); + } +} + +static void restore_prcc(void) +{ + int i; + + for (i = 0; i < UX500_NR_PRCC_BANKS; i++) { + clk_enable(context_prcc[i].clk); + + writel(~context_prcc[i].bus_clk, + context_prcc[i].base + PRCC_PCKDIS); + writel(~context_prcc[i].kern_clk, + context_prcc[i].base + PRCC_KCKDIS); + + writel(context_prcc[i].bus_clk, + context_prcc[i].base + PRCC_PCKEN); + writel(context_prcc[i].kern_clk, + context_prcc[i].base + PRCC_KCKEN); + /* + * Consider having a while over KCK/BCK_STATUS + * to check that all clocks get disabled/enabled + */ + + clk_disable(context_prcc[i].clk); + } +} + +static void save_stm_ape(void) +{ + /* + * TODO: Check with PRCMU developers how STM is handled by PRCMU + * firmware. According to DB5500 design spec there is a "flush" + * mechanism supposed to be used by the PRCMU before power down, + * PRCMU fw might save/restore the following three registers + * at the same time. + */ + context_stm_ape.cr = readl(context_stm_ape.base + + STM_CR_OFFSET); + context_stm_ape.mmc = readl(context_stm_ape.base + + STM_MMC_OFFSET); + context_stm_ape.ter = readl(context_stm_ape.base + + STM_TER_OFFSET); +} + +static void restore_stm_ape(void) +{ + writel(context_stm_ape.ter, + context_stm_ape.base + STM_TER_OFFSET); + writel(context_stm_ape.mmc, + context_stm_ape.base + STM_MMC_OFFSET); + writel(context_stm_ape.cr, + context_stm_ape.base + STM_CR_OFFSET); +} + +static bool inline tpiu_clocked(void) +{ + return ux500_jtag_enabled(); +} + +/* + * Save the context of the Trace Port Interface Unit (TPIU). + * Saving/restoring is needed for the PTM tracing to work together + * with the sleep states ApSleep and ApDeepSleep. + */ +static void save_tpiu(void) +{ + if (!tpiu_clocked()) + return; + + context_tpiu.port_size = readl(context_tpiu.base + + TPIU_PORT_SIZE); + context_tpiu.trigger_counter = readl(context_tpiu.base + + TPIU_TRIGGER_COUNTER); + context_tpiu.trigger_multiplier = readl(context_tpiu.base + + TPIU_TRIGGER_MULTIPLIER); + context_tpiu.current_test_pattern = readl(context_tpiu.base + + TPIU_CURRENT_TEST_PATTERN); + context_tpiu.test_pattern_repeat = readl(context_tpiu.base + + TPIU_TEST_PATTERN_REPEAT); + context_tpiu.formatter = readl(context_tpiu.base + + TPIU_FORMATTER); + context_tpiu.formatter_sync = readl(context_tpiu.base + + TPIU_FORMATTER_SYNC); +} + +/* + * Restore the context of the Trace Port Interface Unit (TPIU). + * Saving/restoring is needed for the PTM tracing to work together + * with the sleep states ApSleep and ApDeepSleep. + */ +static void restore_tpiu(void) +{ + if (!tpiu_clocked()) + return; + + writel(TPIU_UNLOCK_CODE, + context_tpiu.base + TPIU_LOCK_ACCESS_REGISTER); + + writel(context_tpiu.port_size, + context_tpiu.base + TPIU_PORT_SIZE); + writel(context_tpiu.trigger_counter, + context_tpiu.base + TPIU_TRIGGER_COUNTER); + writel(context_tpiu.trigger_multiplier, + context_tpiu.base + TPIU_TRIGGER_MULTIPLIER); + writel(context_tpiu.current_test_pattern, + context_tpiu.base + TPIU_CURRENT_TEST_PATTERN); + writel(context_tpiu.test_pattern_repeat, + context_tpiu.base + TPIU_TEST_PATTERN_REPEAT); + writel(context_tpiu.formatter, + context_tpiu.base + TPIU_FORMATTER); + writel(context_tpiu.formatter_sync, + context_tpiu.base + TPIU_FORMATTER_SYNC); +} + +/* + * Save GIC CPU IF registers + * + * This is per cpu so it needs to be called for each one. + */ +static void save_gic_if_cpu(struct context_gic_cpu *c_gic_cpu) +{ + c_gic_cpu->ctrl = readl_relaxed(c_gic_cpu->base + GIC_CPU_CTRL); + c_gic_cpu->primask = readl_relaxed(c_gic_cpu->base + GIC_CPU_PRIMASK); + c_gic_cpu->binpoint = readl_relaxed(c_gic_cpu->base + GIC_CPU_BINPOINT); +} + +/* + * Restore GIC CPU IF registers + * + * This is per cpu so it needs to be called for each one. + */ +static void restore_gic_if_cpu(struct context_gic_cpu *c_gic_cpu) +{ + writel_relaxed(c_gic_cpu->ctrl, c_gic_cpu->base + GIC_CPU_CTRL); + writel_relaxed(c_gic_cpu->primask, c_gic_cpu->base + GIC_CPU_PRIMASK); + writel_relaxed(c_gic_cpu->binpoint, c_gic_cpu->base + GIC_CPU_BINPOINT); +} + +/* + * Save GIC Distributor Common registers + * + * This context is common. Only one CPU needs to call. + * + * Save SPI (Shared Peripheral Interrupt) settings, IRQ 32-159. + */ +static void save_gic_dist_common(void) +{ + int i; + + context_gic_dist_common.ns = readl_relaxed(context_gic_dist_common.base + + GIC_DIST_ENABLE_NS); + + for (i = 0; i < GIC_DIST_ENABLE_SET_COMMON_NUM; i++) + context_gic_dist_common.enable_set[i] = + readl_relaxed(context_gic_dist_common.base + + GIC_DIST_ENABLE_SET_SPI32 + i * 4); + + for (i = 0; i < GIC_DIST_PRI_COMMON_NUM; i++) + context_gic_dist_common.priority_level[i] = + readl_relaxed(context_gic_dist_common.base + + GIC_DIST_PRI_SPI32 + i * 4); + + for (i = 0; i < GIC_DIST_SPI_TARGET_COMMON_NUM; i++) + context_gic_dist_common.spi_target[i] = + readl_relaxed(context_gic_dist_common.base + + GIC_DIST_SPI_TARGET_SPI32 + i * 4); + + for (i = 0; i < GIC_DIST_CONFIG_COMMON_NUM; i++) + context_gic_dist_common.config[i] = + readl_relaxed(context_gic_dist_common.base + + GIC_DIST_CONFIG_SPI32 + i * 4); +} + +/* + * Restore GIC Distributor Common registers + * + * This context is common. Only one CPU needs to call. + * + * Save SPI (Shared Peripheral Interrupt) settings, IRQ 32-159. + */ +static void restore_gic_dist_common(void) +{ + int i; + + for (i = 0; i < GIC_DIST_CONFIG_COMMON_NUM; i++) + writel_relaxed(context_gic_dist_common.config[i], + context_gic_dist_common.base + + GIC_DIST_CONFIG_SPI32 + i * 4); + + for (i = 0; i < GIC_DIST_SPI_TARGET_COMMON_NUM; i++) + writel_relaxed(context_gic_dist_common.spi_target[i], + context_gic_dist_common.base + + GIC_DIST_SPI_TARGET_SPI32 + i * 4); + + for (i = 0; i < GIC_DIST_PRI_COMMON_NUM; i++) + writel_relaxed(context_gic_dist_common.priority_level[i], + context_gic_dist_common.base + + GIC_DIST_PRI_SPI32 + i * 4); + + for (i = 0; i < GIC_DIST_ENABLE_SET_COMMON_NUM; i++) + writel_relaxed(context_gic_dist_common.enable_set[i], + context_gic_dist_common.base + + GIC_DIST_ENABLE_SET_SPI32 + i * 4); + + writel_relaxed(context_gic_dist_common.ns, + context_gic_dist_common.base + GIC_DIST_ENABLE_NS); +} + +/* + * Save GIC Dist CPU registers + * + * This needs to be called by all cpu:s which will not call + * save_gic_dist_common(). Only the registers of the GIC which are + * banked will be saved. + */ +static void save_gic_dist_cpu(struct context_gic_dist_cpu *c_gic) +{ + int i; + + for (i = 0; i < GIC_DIST_ENABLE_SET_CPU_NUM; i++) + c_gic->enable_set[i] = + readl_relaxed(c_gic->base + + GIC_DIST_ENABLE_SET_SPI0 + i * 4); + + for (i = 0; i < GIC_DIST_PRI_CPU_NUM; i++) + c_gic->priority_level[i] = + readl_relaxed(c_gic->base + + GIC_DIST_PRI_SPI0 + i * 4); + + for (i = 0; i < GIC_DIST_SPI_TARGET_CPU_NUM; i++) + c_gic->spi_target[i] = + readl_relaxed(c_gic->base + + GIC_DIST_SPI_TARGET_SPI0 + i * 4); + + for (i = 0; i < GIC_DIST_CONFIG_CPU_NUM; i++) + c_gic->config[i] = + readl_relaxed(c_gic->base + + GIC_DIST_CONFIG_SPI0 + i * 4); +} + +/* + * Restore GIC Dist CPU registers + * + * This needs to be called by all cpu:s which will not call + * restore_gic_dist_common(). Only the registers of the GIC which are + * banked will be saved. + */ +static void restore_gic_dist_cpu(struct context_gic_dist_cpu *c_gic) +{ + int i; + + for (i = 0; i < GIC_DIST_CONFIG_CPU_NUM; i++) + writel_relaxed(c_gic->config[i], + c_gic->base + + GIC_DIST_CONFIG_SPI0 + i * 4); + + for (i = 0; i < GIC_DIST_SPI_TARGET_CPU_NUM; i++) + writel_relaxed(c_gic->spi_target[i], + c_gic->base + + GIC_DIST_SPI_TARGET_SPI0 + i * 4); + + for (i = 0; i < GIC_DIST_PRI_CPU_NUM; i++) + writel_relaxed(c_gic->priority_level[i], + c_gic->base + + GIC_DIST_PRI_SPI0 + i * 4); + + for (i = 0; i < GIC_DIST_ENABLE_SET_CPU_NUM; i++) + writel_relaxed(c_gic->enable_set[i], + c_gic->base + + GIC_DIST_ENABLE_SET_SPI0 + i * 4); +} + +/* + * Disable interrupts that are not necessary + * to have turned on during ApDeepSleep. + */ +void context_gic_dist_disable_unneeded_irqs(void) +{ + writel(0xffffffff, + context_gic_dist_common.base + + GIC_DIST_ENABLE_CLEAR_0); + + writel(0xffffffff, + context_gic_dist_common.base + + GIC_DIST_ENABLE_CLEAR_32); + + /* Leave PRCMU IRQ 0 and 1 enabled */ + writel(0xffff3fff, + context_gic_dist_common.base + + GIC_DIST_ENABLE_CLEAR_64); + + writel(0xffffffff, + context_gic_dist_common.base + + GIC_DIST_ENABLE_CLEAR_96); + + writel(0xffffffff, + context_gic_dist_common.base + + GIC_DIST_ENABLE_CLEAR_128); +} + +static void save_scu(void) +{ + context_scu.ctrl = + readl_relaxed(context_scu.base + SCU_CTRL); + context_scu.cpu_pwrstatus = + readl_relaxed(context_scu.base + SCU_CPU_STATUS); + context_scu.inv_all_nonsecure = + readl_relaxed(context_scu.base + SCU_INVALIDATE); + context_scu.filter_start_addr = + readl_relaxed(context_scu.base + SCU_FILTER_STARTADDR); + context_scu.filter_end_addr = + readl_relaxed(context_scu.base + SCU_FILTER_ENDADDR); + context_scu.access_ctrl_sac = + readl_relaxed(context_scu.base + SCU_ACCESS_CTRL_SAC); +} + +static void restore_scu(void) +{ + writel_relaxed(context_scu.ctrl, + context_scu.base + SCU_CTRL); + writel_relaxed(context_scu.cpu_pwrstatus, + context_scu.base + SCU_CPU_STATUS); + writel_relaxed(context_scu.inv_all_nonsecure, + context_scu.base + SCU_INVALIDATE); + writel_relaxed(context_scu.filter_start_addr, + context_scu.base + SCU_FILTER_STARTADDR); + writel_relaxed(context_scu.filter_end_addr, + context_scu.base + SCU_FILTER_ENDADDR); + writel_relaxed(context_scu.access_ctrl_sac, + context_scu.base + SCU_ACCESS_CTRL_SAC); +} + +/* + * Save VAPE context + */ +void context_vape_save(void) +{ + atomic_notifier_call_chain(&context_ape_notifier_list, + CONTEXT_APE_SAVE, NULL); + + if (cpu_is_u5500()) + u5500_context_save_icn(); + if (cpu_is_u8500()) + u8500_context_save_icn(); + if (cpu_is_u9540()) + u9540_context_save_icn(); + + save_stm_ape(); + + save_tpiu(); + + save_prcc(); +} + +/* + * Restore VAPE context + */ +void context_vape_restore(void) +{ + restore_prcc(); + + restore_tpiu(); + + restore_stm_ape(); + + if (cpu_is_u5500()) + u5500_context_restore_icn(); + if (cpu_is_u8500()) + u8500_context_restore_icn(); + if (cpu_is_u9540()) + u9540_context_restore_icn(); + + atomic_notifier_call_chain(&context_ape_notifier_list, + CONTEXT_APE_RESTORE, NULL); +} + +/* + * Save FSMC registers that will be reset + * during power save. + */ +void context_fsmc_save(void) +{ + fsmc_base_addr = ioremap_nocache(U8500_FSMC_BASE, 8); + fsmc_bcr0 = readl(fsmc_base_addr); +} + +/* + * Restore FSMC registers that will be reset + * during power save. + */ +void context_fsmc_restore(void) +{ + writel(fsmc_bcr0, fsmc_base_addr); + iounmap(fsmc_base_addr); +} + +/* + * Save GPIO registers that might be modified + * for power save reasons. + */ +void context_gpio_save(void) +{ + int i; + + for (i = 0; i < GPIO_NUM_BANKS; i++) { + gpio_save[i][0] = readl(gpio_bankaddr[i] + NMK_GPIO_AFSLA); + gpio_save[i][1] = readl(gpio_bankaddr[i] + NMK_GPIO_AFSLB); + gpio_save[i][2] = readl(gpio_bankaddr[i] + NMK_GPIO_PDIS); + gpio_save[i][3] = readl(gpio_bankaddr[i] + NMK_GPIO_DIR); + gpio_save[i][4] = readl(gpio_bankaddr[i] + NMK_GPIO_DAT); + gpio_save[i][6] = readl(gpio_bankaddr[i] + NMK_GPIO_SLPC); + } + +} + +/* + * Restore GPIO registers that might be modified + * for power save reasons. + */ +void context_gpio_restore(void) +{ + int i; + u32 output_state; + u32 pull_up; + u32 pull_down; + u32 pull; + + for (i = 0; i < GPIO_NUM_BANKS; i++) { + writel(gpio_save[i][2], gpio_bankaddr[i] + NMK_GPIO_PDIS); + + writel(gpio_save[i][3], gpio_bankaddr[i] + NMK_GPIO_DIR); + + /* Set the high outputs. outpute_state = GPIO_DIR & GPIO_DAT */ + output_state = gpio_save[i][3] & gpio_save[i][4]; + writel(output_state, gpio_bankaddr[i] + NMK_GPIO_DATS); + + /* + * Set the low outputs. + * outpute_state = ~(GPIO_DIR & GPIO_DAT) & GPIO_DIR + */ + output_state = ~(gpio_save[i][3] & gpio_save[i][4]) & + gpio_save[i][3]; + writel(output_state, gpio_bankaddr[i] + NMK_GPIO_DATC); + + /* + * Restore pull up/down. + * Only write pull up/down settings on inputs where + * PDIS is not set. + * pull = (~GPIO_DIR & ~GPIO_PDIS) + */ + pull = (~gpio_save[i][3] & ~gpio_save[i][2]); + nmk_gpio_read_pull(i, &pull_up); + + pull_down = pull & ~pull_up; + pull_up = pull & pull_up; + /* Set pull ups */ + writel(pull_up, gpio_bankaddr[i] + NMK_GPIO_DATS); + /* Set pull downs */ + writel(pull_down, gpio_bankaddr[i] + NMK_GPIO_DATC); + + writel(gpio_save[i][6], gpio_bankaddr[i] + NMK_GPIO_SLPC); + } + +} + +/* + * Restore GPIO mux registers that might be modified + * for power save reasons. + */ +void context_gpio_restore_mux(void) +{ + int i; + + /* Change mux settings */ + for (i = 0; i < GPIO_NUM_BANKS; i++) { + writel(gpio_save[i][0], gpio_bankaddr[i] + NMK_GPIO_AFSLA); + writel(gpio_save[i][1], gpio_bankaddr[i] + NMK_GPIO_AFSLB); + } +} + +/* + * Safe sequence used to switch IOs between GPIO and Alternate-C mode: + * - Save SLPM registers (Not done.) + * - Set SLPM=0 for the IOs you want to switch. (We assume that all + * SLPM registers already are 0 except for the ones that wants to + * have the mux connected in sleep (e.g modem STM)). + * - Configure the GPIO registers for the IOs that are being switched + * - Set IOFORCE=1 + * - Modify the AFLSA/B registers for the IOs that are being switched + * - Set IOFORCE=0 + * - Restore SLPM registers (Not done.) + * - Any spurious wake up event during switch sequence to be ignored + * and cleared + */ +void context_gpio_mux_safe_switch(bool begin) +{ + int i; + + static u32 rwimsc[GPIO_NUM_BANKS]; + static u32 fwimsc[GPIO_NUM_BANKS]; + + if (begin) { + for (i = 0; i < GPIO_NUM_BANKS; i++) { + /* Save registers */ + rwimsc[i] = readl(gpio_bankaddr[i] + NMK_GPIO_RWIMSC); + fwimsc[i] = readl(gpio_bankaddr[i] + NMK_GPIO_FWIMSC); + + /* Prevent spurious wakeups */ + writel(0, gpio_bankaddr[i] + NMK_GPIO_RWIMSC); + writel(0, gpio_bankaddr[i] + NMK_GPIO_FWIMSC); + } + + ux500_pm_prcmu_set_ioforce(true); + } else { + ux500_pm_prcmu_set_ioforce(false); + + /* Restore wake up settings */ + for (i = 0; i < GPIO_NUM_BANKS; i++) { + writel(rwimsc[i], gpio_bankaddr[i] + NMK_GPIO_RWIMSC); + writel(fwimsc[i], gpio_bankaddr[i] + NMK_GPIO_FWIMSC); + } + } +} + +/* + * Save common + * + * This function must be called once for all cores before going to deep sleep. + */ +void context_varm_save_common(void) +{ + atomic_notifier_call_chain(&context_arm_notifier_list, + CONTEXT_ARM_COMMON_SAVE, NULL); + + /* Save common parts */ + save_gic_dist_common(); + save_scu(); +} + +/* + * Restore common + * + * This function must be called once for all cores when waking up from deep + * sleep. + */ +void context_varm_restore_common(void) +{ + /* Restore common parts */ + restore_scu(); + restore_gic_dist_common(); + + atomic_notifier_call_chain(&context_arm_notifier_list, + CONTEXT_ARM_COMMON_RESTORE, NULL); +} + +/* + * Save core + * + * This function must be called once for each cpu core before going to deep + * sleep. + */ +void context_varm_save_core(void) +{ + int cpu = smp_processor_id(); + + atomic_notifier_call_chain(&context_arm_notifier_list, + CONTEXT_ARM_CORE_SAVE, NULL); + + per_cpu(varm_cp15_pointer, cpu) = per_cpu(varm_cp15_backup_stack, cpu); + + /* Save core */ + twd_save(); + save_gic_if_cpu(&per_cpu(context_gic_cpu, cpu)); + save_gic_dist_cpu(&per_cpu(context_gic_dist_cpu, cpu)); + context_save_cp15_registers(&per_cpu(varm_cp15_pointer, cpu)); +} + +/* + * Restore core + * + * This function must be called once for each cpu core when waking up from + * deep sleep. + */ +void context_varm_restore_core(void) +{ + int cpu = smp_processor_id(); + + /* Restore core */ + context_restore_cp15_registers(&per_cpu(varm_cp15_pointer, cpu)); + restore_gic_dist_cpu(&per_cpu(context_gic_dist_cpu, cpu)); + restore_gic_if_cpu(&per_cpu(context_gic_cpu, cpu)); + twd_restore(); + + atomic_notifier_call_chain(&context_arm_notifier_list, + CONTEXT_ARM_CORE_RESTORE, NULL); +} + +/* + * Save CPU registers + * + * This function saves ARM registers. + */ +void context_save_cpu_registers(void) +{ + int cpu = smp_processor_id(); + + per_cpu(varm_registers_pointer, cpu) = + per_cpu(varm_registers_backup_stack, cpu); + context_save_arm_registers(&per_cpu(varm_registers_pointer, cpu)); +} + +/* + * Restore CPU registers + * + * This function restores ARM registers. + */ +void context_restore_cpu_registers(void) +{ + int cpu = smp_processor_id(); + + context_restore_arm_registers(&per_cpu(varm_registers_pointer, cpu)); +} + +/* + * This function stores CP15 registers related to cache and mmu + * in backup SRAM. It also stores stack pointer, CPSR + * and return address for the PC in backup SRAM and + * does wait for interrupt. + */ +void context_save_to_sram_and_wfi(bool cleanL2cache) +{ + int cpu = smp_processor_id(); + + context_save_to_sram_and_wfi_internal(backup_sram_storage[cpu], + cleanL2cache); +} + +static int __init context_init(void) +{ + int i; + void __iomem *ux500_backup_ptr; + + /* allocate backup pointer for RAM data */ + ux500_backup_ptr = (void *)__get_free_pages(GFP_KERNEL, + get_order(U8500_BACKUPRAM_SIZE)); + + if (!ux500_backup_ptr) { + pr_warning("context: could not allocate backup memory\n"); + return -ENOMEM; + } + + /* + * ROM code addresses to store backup contents, + * pass the physical address of back up to ROM code + */ + writel(virt_to_phys(ux500_backup_ptr), + IO_ADDRESS(U8500_EXT_RAM_LOC_BACKUPRAM_ADDR)); + + if (cpu_is_u5500()) { + writel(IO_ADDRESS(U5500_PUBLIC_BOOT_ROM_BASE), + IO_ADDRESS(U8500_CPU0_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); + + writel(IO_ADDRESS(U5500_PUBLIC_BOOT_ROM_BASE), + IO_ADDRESS(U8500_CPU1_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); + + context_tpiu.base = ioremap(U5500_TPIU_BASE, SZ_4K); + context_stm_ape.base = ioremap(U5500_STM_REG_BASE, SZ_4K); + context_scu.base = ioremap(U5500_SCU_BASE, SZ_4K); + + context_prcc[0].base = ioremap(U5500_CLKRST1_BASE, SZ_4K); + context_prcc[1].base = ioremap(U5500_CLKRST2_BASE, SZ_4K); + context_prcc[2].base = ioremap(U5500_CLKRST3_BASE, SZ_4K); + context_prcc[3].base = ioremap(U5500_CLKRST5_BASE, SZ_4K); + context_prcc[4].base = ioremap(U5500_CLKRST6_BASE, SZ_4K); + + context_gic_dist_common.base = ioremap(U5500_GIC_DIST_BASE, SZ_4K); + per_cpu(context_gic_cpu, 0).base = ioremap(U5500_GIC_CPU_BASE, SZ_4K); + } else if (cpu_is_u8500() || cpu_is_u9540()) { + /* Give logical address to backup RAM. For both CPUs */ + if (cpu_is_u9540()) { + writel(IO_ADDRESS_DB9540_ROM(U9540_PUBLIC_BOOT_ROM_BASE), + IO_ADDRESS(U8500_CPU0_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); + + writel(IO_ADDRESS_DB9540_ROM(U9540_PUBLIC_BOOT_ROM_BASE), + IO_ADDRESS(U8500_CPU1_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); + } else { + writel(IO_ADDRESS(U8500_PUBLIC_BOOT_ROM_BASE), + IO_ADDRESS(U8500_CPU0_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); + + writel(IO_ADDRESS(U8500_PUBLIC_BOOT_ROM_BASE), + IO_ADDRESS(U8500_CPU1_BACKUPRAM_ADDR_PUBLIC_BOOT_ROM_LOG_ADDR)); + } + + context_tpiu.base = ioremap(U8500_TPIU_BASE, SZ_4K); + context_stm_ape.base = ioremap(U8500_STM_REG_BASE, SZ_4K); + context_scu.base = ioremap(U8500_SCU_BASE, SZ_4K); + + /* PERIPH4 is always on, so no need saving prcc */ + context_prcc[0].base = ioremap(U8500_CLKRST1_BASE, SZ_4K); + context_prcc[1].base = ioremap(U8500_CLKRST2_BASE, SZ_4K); + context_prcc[2].base = ioremap(U8500_CLKRST3_BASE, SZ_4K); + context_prcc[3].base = ioremap(U8500_CLKRST5_BASE, SZ_4K); + context_prcc[4].base = ioremap(U8500_CLKRST6_BASE, SZ_4K); + + context_gic_dist_common.base = ioremap(U8500_GIC_DIST_BASE, SZ_4K); + per_cpu(context_gic_cpu, 0).base = ioremap(U8500_GIC_CPU_BASE, SZ_4K); + } + + per_cpu(context_gic_dist_cpu, 0).base = context_gic_dist_common.base; + + for (i = 1; i < num_possible_cpus(); i++) { + per_cpu(context_gic_cpu, i).base + = per_cpu(context_gic_cpu, 0).base; + per_cpu(context_gic_dist_cpu, i).base + = per_cpu(context_gic_dist_cpu, 0).base; + } + + for (i = 0; i < ARRAY_SIZE(context_prcc); i++) { + const int clusters[] = {1, 2, 3, 5, 6}; + char clkname[10]; + + snprintf(clkname, sizeof(clkname), "PERIPH%d", clusters[i]); + + context_prcc[i].clk = clk_get_sys(clkname, NULL); + BUG_ON(IS_ERR(context_prcc[i].clk)); + } + + if (cpu_is_u8500()) { + u8500_context_init(); + } else if (cpu_is_u5500()) { + u5500_context_init(); + } else if (cpu_is_u9540()) { + u9540_context_init(); + } else { + printk(KERN_ERR "context: unknown hardware!\n"); + return -EINVAL; + } + + return 0; +} +subsys_initcall(context_init); diff --git a/arch/arm/mach-ux500/pm/context_arm.S b/arch/arm/mach-ux500/pm/context_arm.S new file mode 100644 index 00000000000..edb894d6a35 --- /dev/null +++ b/arch/arm/mach-ux500/pm/context_arm.S @@ -0,0 +1,409 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> + * Rickard Andersson <rickard.andersson@stericsson.com> for + * ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#include <linux/linkage.h> +#include <mach/hardware.h> +#include <asm/hardware/cache-l2x0.h> + +/* + * Save and increment macro + */ +.macro SAVE_AND_INCREMENT FROM_REG TO_REG + str \FROM_REG, [\TO_REG], #+4 +.endm + +/* + * Decrement and restore macro + */ +.macro DECREMENT_AND_RESTORE FROM_REG TO_REG + ldr \TO_REG, [\FROM_REG, #-4]! +.endm + +/* + * Save ARM registers + * + * This function must be called in supervisor mode. + * + * r0 = address to backup stack pointer + * + * Backup stack operations: + * + {sp, lr}^ + * + cpsr + * + {r3, r8-r14} (FIQ mode: r3=spsr) + * + {r3, r13, r14} (IRQ mode: r3=spsr) + * + {r3, r13, r14} (abort mode: r3=spsr) + * + {r3, r13, r14} (undef mode: r3=spsr) + */ + .align + .section ".text", "ax" +ENTRY(context_save_arm_registers) + stmfd sp!, {r1, r2, r3, lr} @ Save on stack + ldr r1, [r0] @ Read backup stack pointer + +ARM( stmia r1, {sp, lr}^ ) @ Store user mode sp and lr + @ registers +ARM( add r1, r1, #8 ) @ Update backup pointer (not + @ done in previous instruction) +THUMB( str sp, [r1], #+4 ) +THUMB( str lr, [r1], #+4 ) + + mrs r2, cpsr @ Get CPSR + SAVE_AND_INCREMENT r2 r1 @ Save CPSR register + orr r2, r2, #0xc0 @ Disable FIQ and IRQ + bic r2, r2, #0x1f @ Setup r2 to change mode + + @ The suffix to CPSR refers to which field(s) of the CPSR is + @ rereferenced (you can specify one or more). Defined fields are: + @ + @ c - control + @ x - extension + @ s - status + @ f - flags + + orr r3, r2, #0x11 @ Save FIQ mode registers + msr cpsr_cxsf, r3 + mrs r3, spsr +ARM( stmia r1!, {r3, r8-r14} ) +THUMB( stmia r1!, {r3, r8-r12, r14} ) +THUMB( str r13, [r1], #+4 ) + + + orr r3, r2, #0x12 @ Save IRQ mode registers + msr cpsr_cxsf, r3 + mrs r3, spsr +ARM( stmia r1!, {r3, r13, r14} ) +THUMB( stmia r1!, {r3, r14} ) +THUMB( str r13, [r1], #+4 ) + + orr r3, r2, #0x17 @ Save abort mode registers + + @ common mode registers + msr cpsr_cxsf, r3 + mrs r3, spsr +ARM( stmia r1!, {r3, r13, r14} ) +THUMB( stmia r1!, {r3, r14} ) +THUMB( str r13, [r1], #+4 ) + + orr r3, r2, #0x1B @ Save undef mode registers + msr cpsr_cxsf, r3 + mrs r3, spsr +ARM( stmia r1!, {r3, r13, r14} ) +THUMB( stmia r1!, {r3, r14} ) +THUMB( str r13, [r1], #+4 ) + + orr r3, r2, #0x13 @ Return to supervisor mode + msr cpsr_cxsf, r3 + + str r1, [r0] @ Write backup stack pointer + ldmfd sp!, {r1, r2, r3, pc} @ Restore registers and return + + + +/* + * Restore ARM registers + * + * This function must be called in supervisor mode. + * + * r0 = address to backup stack pointer + * + * Backup stack operations: + * - {r3, r13, r14} (undef mode: spsr=r3) + * - {r3, r13, r14} (abort mode: spsr=r3) + * - {r3, r13, r14} (IRQ mode: spsr=r3) + * - {r3, r8-r14} (FIQ mode: spsr=r3) + * - cpsr + * - {sp, lr}^ + */ + .align + .section ".text", "ax" +ENTRY(context_restore_arm_registers) + stmfd sp!, {r1, r2, r3, lr} @ Save on stack + ldr r1, [r0] @ Read backup stack pointer + + mrs r2, cpsr @ Get CPSR + orr r2, r2, #0xc0 @ Disable FIQ and IRQ + bic r2, r2, #0x1f @ Setup r2 to change mode + + orr r3, r2, #0x1b @ Restore undef mode registers + msr cpsr_cxsf, r3 +ARM( ldmdb r1!, {r3, r13, r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r14} ) + msr spsr_cxsf, r3 + + orr r3, r2, #0x17 @ Restore abort mode registers + msr cpsr_cxsf, r3 +ARM( ldmdb r1!, {r3, r13, r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r14} ) + msr spsr_cxsf, r3 + + orr r3, r2, #0x12 @ Restore IRQ mode registers + msr cpsr_cxsf, r3 +ARM( ldmdb r1!, {r3, r13, r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r14} ) + msr spsr_cxsf, r3 + + orr r3, r2, #0x11 @ Restore FIQ mode registers + msr cpsr_cxsf, r3 +ARM( ldmdb r1!, {r3, r8-r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r8-r12, r14} ) + + msr spsr_cxsf, r3 + + DECREMENT_AND_RESTORE r1 r3 @ Restore cpsr register + msr cpsr_cxsf, r3 + +ARM( ldmdb r1, {sp, lr}^ ) @ Restore sp and lr registers +ARM( sub r1, r1, #8 ) @ Update backup pointer (not + @ done in previous instruction) +THUMB( ldr lr, [r1], #-4 ) +THUMB( ldr sp, [r1], #-4 ) + + str r1, [r0] @ Write backup stack pointer + ldmfd sp!, {r1, r2, r3, pc} @ Restore registers and return + + + +/* + * Save CP15 registers + * + * This function must be called in supervisor mode. + * + * r0 = address to backup stack pointer + * + * TTBR0, TTBR1, TTBRC, DACR CP15 registers are restored by boot ROM from SRAM. + */ + .align 4 + .section ".text", "ax" +ENTRY(context_save_cp15_registers) + stmfd sp!, {r1, r2, r3, lr} @ Save on stack (r3 is saved due + @ to 8 byte aligned stack) + ldr r1, [r0] @ Read backup stack pointer + + mrc p15, 0, r2, c12, c0, 0 @ Read Non-secure Vector Base + @ Address Register + SAVE_AND_INCREMENT r2 r1 + + mrc p15, 0, r2, c10, c2, 0 @ Access primary memory region + @ remap register + SAVE_AND_INCREMENT r2 r1 + + mrc p15, 0, r2, c10, c2, 1 @ Access normal memory region + @ remap register + SAVE_AND_INCREMENT r2 r1 + + mrc p15, 0, r2, c13, c0, 1 @ Read Context ID Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c13, c0, 2 @ Read Thread ID registers, + @ this register is both user + @ and privileged R/W accessible + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c13, c0, 3 @ Read Thread ID registers, + @ this register is user + @ read-only and privileged R/W + @ accessible. + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c13, c0, 4 @ Read Thread ID registers, + @ this register is privileged + @ R/W accessible only. + SAVE_AND_INCREMENT r2 r1 + + mrc p15, 2, r2, c0, c0, 0 @ Cache Size Selection Register + SAVE_AND_INCREMENT r2 r1 + + mrc p15, 0, r2, c9, c12, 0 @ Read PMNC Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c12, 1 @ Read PMCNTENSET Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c12, 5 @ Read PMSELR Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c13, 0 @ Read PMCCNTR Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c13, 1 @ Read PMXEVTYPER Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c14, 0 @ Read PMUSERENR Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c14, 1 @ Read PMINTENSET Register + SAVE_AND_INCREMENT r2 r1 + mrc p15, 0, r2, c9, c14, 2 @ Read PMINTENCLR Register + SAVE_AND_INCREMENT r2 r1 + + mrc p15, 0, r2, c1, c0, 2 @ Read CPACR Register + SAVE_AND_INCREMENT r2 r1 + + str r1, [r0] @ Write backup stack pointer + ldmfd sp!, {r1, r2, r3, pc} @ Restore registers and return + + + +/* + * Restore CP15 registers + * + * This function must be called in supervisor mode. + * + * r0 = address to backup stack pointer + */ + .align 4 + .section ".text", "ax" +ENTRY(context_restore_cp15_registers) + stmfd sp!, {r1, r2, r3, lr} @ Save on stack (r3 is saved due + @ to 8 byte aligned stack) + ldr r1, [r0] @ Read backup stack pointer + + DECREMENT_AND_RESTORE r1 r2 @ Write CPACR register + mcr p15, 0, r2, c1, c0, 2 + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c14, 2 @ Write PMINTENCLR Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c14, 1 @ Write PMINTENSET Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c14, 0 @ Write PMUSERENR Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c13, 1 @ Write PMXEVTYPER Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c13, 0 @ Write PMCCNTR Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c12, 5 @ Write PMSELR Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c12, 1 @ Write PMCNTENSET Register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c9, c12, 0 @ Write PMNC Register + + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 2, r2, c0, c0, 0 @ Cache Size Selection Register + + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c13, c0, 4 @ Write Thread ID registers, + @ this register is privileged + @ R/W accessible only + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c13, c0, 3 @ Write Thread ID registers, + @ this register is user + @ read-only and privileged R/W + @ accessible + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c13, c0, 2 @ Write Thread ID registers, + @ this register is both user + @ and privileged R/W accessible + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c13, c0, 1 @ Write Context ID Register + + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c10, c2, 1 @ Access normal memory region + @ remap register + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c10, c2, 0 @ Access primary memory region + @ remap register + + DECREMENT_AND_RESTORE r1 r2 + mcr p15, 0, r2, c12, c0, 0 @ Write Non-secure Vector Base + @ Address Register + + str r1, [r0] @ Write backup stack pointer + ldmfd sp!, {r1, r2, r3, pc} @ Restore registers and return + + +/* + * L1 cache clean function. Commit 'dirty' data from L1 + * to L2 cache. + * + * r0, r1, r2, used locally + * + */ + .align 4 + .section ".text", "ax" +ENTRY(context_clean_l1_cache_all) + + mov r0, #0 @ swith to cache level 0 + @ (L1 cache) + mcr p15, 2, r0, c0, c0, 0 @ select current cache level + @ in cssr + + dmb + mov r1, #0 @ r1 = way index +wayLoopL1clean: + mov r0, #0 @ r0 = line index +lineLoopL1clean: + mov r2, r1, lsl #30 @ TODO: OK to hard-code + @ SoC-specific L1 cache details? + mov r3, r0, lsl #5 + add r2, r3 +@ add r2, r0, lsl #5 + mcr p15, 0, r2, c7, c10, 2 @ Clean cache by set/way + add r0, r0, #1 + cmp r0, #256 @ TODO: Ok with hard-coded + @ set/way sizes or do we have to + @ read them from ARM regs? Is it + @ set correctly in silicon? + bne lineLoopL1clean + add r1, r1, #1 + cmp r1, #4 @ TODO: Ditto, sizes... + bne wayLoopL1clean + + dsb + isb + mov pc, lr + +ENDPROC(context_clean_l1_cache_all) + +/* + * Last saves to backup RAM, cache clean and WFI + * + * r0 = address to backup_sram_storage base adress + * r1 = indicate whether also L2 cache should be cleaned + */ + .align 4 + .section ".text", "ax" +ENTRY(context_save_to_sram_and_wfi_internal) + + stmfd sp!, {r2-r12, lr} @ save on stack. + + mrc p15, 0, r2, c1, c0, 0 @ read cp15 system control + @ register + str r2, [r0, #0x00] + mrc p15, 0, r2, c2, c0, 0 @ read cp15 ttb0 register + str r2, [r0, #0x04] + mrc p15, 0, r2, c2, c0, 1 @ read cp15 ttb1 register + str r2, [r0, #0x08] + mrc p15, 0, r2, c2, c0, 2 @ read cp15 ttb control register + str r2, [r0, #0x0C] + mrc p15, 0, r2, c3, c0, 0 @ read domain access control + @ register + str r2, [r0, #0x10] + + ldr r2, =return_here + str r2, [r0, #0x14] @ save program counter restore + @ value to backup_sram_storage + mrs r2, cpsr + str r2, [r0, #0x18] @ save cpsr to + @ backup_sram_storage + str sp, [r0, #0x1c] @ save sp to backup_sram_storage + + mov r4, r1 @ Set r4 = cleanL2cache, r1 + @ will be destroyed by + @ v7_clean_l1_cache_all + + bl context_clean_l1_cache_all @ Commit all dirty data in L1 + @ cache to L2 without + @ invalidating + + dsb @ data synchronization barrier + isb @ instruction synchronization + @ barrier + wfi @ wait for interrupt + +return_here: @ both cores return here + @ now we are out deep sleep + @ with all the context lost + @ except pc, sp and cpsr + + ldmfd sp!, {r2-r12, pc} @ restore from stack + diff --git a/arch/arm/mach-ux500/pm/performance.c b/arch/arm/mach-ux500/pm/performance.c new file mode 100644 index 00000000000..04aca3cb5bd --- /dev/null +++ b/arch/arm/mach-ux500/pm/performance.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * + * Author: Johan Rudholm <johan.rudholm@stericsson.com> + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + */ + +#include <linux/kernel.h> +#include <linux/genhd.h> +#include <linux/major.h> +#include <linux/cdev.h> +#include <linux/kernel_stat.h> +#include <linux/workqueue.h> +#include <linux/kernel.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <linux/cpu.h> +#include <linux/pm_qos.h> + +#include <mach/irqs.h> + +#define WLAN_PROBE_DELAY 3000 /* 3 seconds */ +#define WLAN_LIMIT (3000/3) /* If we have more than 1000 irqs per second */ + +/* + * MMC TODO: + * o Develop a more power-aware algorithm + * o Make the parameters visible through debugfs + * o Get the value of CONFIG_MMC_BLOCK_MINORS in runtime instead, since + * it may be altered by drivers/mmc/card/block.c + */ + +/* Sample reads and writes every n ms */ +#define PERF_MMC_PROBE_DELAY 1000 +/* Read threshold, sectors/second */ +#define PERF_MMC_LIMIT_READ 10240 +/* Write threshold, sectors/second */ +#define PERF_MMC_LIMIT_WRITE 8192 +/* Nr of MMC devices */ +#define PERF_MMC_HOSTS 8 + +/* + * Rescan for new MMC devices every + * PERF_MMC_PROBE_DELAY * PERF_MMC_RESCAN_CYCLES ms + */ +#define PERF_MMC_RESCAN_CYCLES 10 + +#ifdef CONFIG_MMC_BLOCK +static struct delayed_work work_mmc; +#endif + +static struct delayed_work work_wlan_workaround; +static struct pm_qos_request wlan_pm_qos_latency; +static bool wlan_pm_qos_is_latency_0; + +static void wlan_load(struct work_struct *work) +{ + int cpu; + unsigned int num_irqs = 0; + static unsigned int old_num_irqs = UINT_MAX; + + for_each_online_cpu(cpu) + num_irqs += kstat_irqs_cpu(IRQ_DB8500_SDMMC1, cpu); + + if ((num_irqs > old_num_irqs) && + (num_irqs - old_num_irqs) > WLAN_LIMIT) { + prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "wlan", 125); + if (!wlan_pm_qos_is_latency_0) { + /* + * The wake up latency is set to 0 to prevent + * the system from going to sleep. This improves + * the wlan throughput in DMA mode. + * The wake up latency from sleep adds ~5% overhead + * for TX in some cases. + * This change doesn't increase performance for wlan + * PIO since the CPU usage prevents sleep in this mode. + */ + pm_qos_add_request(&wlan_pm_qos_latency, + PM_QOS_CPU_DMA_LATENCY, 0); + wlan_pm_qos_is_latency_0 = true; + } + } else { + prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "wlan", 25); + if (wlan_pm_qos_is_latency_0) { + pm_qos_remove_request(&wlan_pm_qos_latency); + wlan_pm_qos_is_latency_0 = false; + } + } + + old_num_irqs = num_irqs; + + schedule_delayed_work_on(0, + &work_wlan_workaround, + msecs_to_jiffies(WLAN_PROBE_DELAY)); +} + +#ifdef CONFIG_MMC_BLOCK +/* + * Loop through every CONFIG_MMC_BLOCK_MINORS'th minor device for + * MMC_BLOCK_MAJOR, get the struct gendisk for each device. Returns + * nr of found disks. Populate mmc_disks. + */ +static int scan_mmc_devices(struct gendisk *mmc_disks[]) +{ + dev_t devnr; + int i, j = 0, part; + struct gendisk *mmc_devices[256 / CONFIG_MMC_BLOCK_MINORS]; + + memset(&mmc_devices, 0, sizeof(mmc_devices)); + + for (i = 0; i * CONFIG_MMC_BLOCK_MINORS < 256; i++) { + devnr = MKDEV(MMC_BLOCK_MAJOR, i * CONFIG_MMC_BLOCK_MINORS); + mmc_devices[i] = get_gendisk(devnr, &part); + + /* Invalid capacity of device, do not add to list */ + if (!mmc_devices[i] || !get_capacity(mmc_devices[i])) + continue; + + mmc_disks[j] = mmc_devices[i]; + j++; + + if (j == PERF_MMC_HOSTS) + break; + } + + return j; +} + +/* + * Sample sectors read and written to any MMC devices, update PRCMU + * qos requirement + */ +static void mmc_load(struct work_struct *work) +{ + static unsigned long long old_sectors_read[PERF_MMC_HOSTS]; + static unsigned long long old_sectors_written[PERF_MMC_HOSTS]; + static struct gendisk *mmc_disks[PERF_MMC_HOSTS]; + static int cycle, nrdisk; + static bool old_mode; + unsigned long long sectors; + bool new_mode = false; + int i; + + if (!cycle) { + memset(&mmc_disks, 0, sizeof(mmc_disks)); + nrdisk = scan_mmc_devices(mmc_disks); + cycle = PERF_MMC_RESCAN_CYCLES; + } + cycle--; + + for (i = 0; i < nrdisk; i++) { + sectors = part_stat_read(&(mmc_disks[i]->part0), + sectors[READ]); + + if (old_sectors_read[i] && + sectors > old_sectors_read[i] && + (sectors - old_sectors_read[i]) > + PERF_MMC_LIMIT_READ) + new_mode = true; + + old_sectors_read[i] = sectors; + sectors = part_stat_read(&(mmc_disks[i]->part0), + sectors[WRITE]); + + if (old_sectors_written[i] && + sectors > old_sectors_written[i] && + (sectors - old_sectors_written[i]) > + PERF_MMC_LIMIT_WRITE) + new_mode = true; + + old_sectors_written[i] = sectors; + } + + if (!old_mode && new_mode) + prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "mmc", 125); + + if (old_mode && !new_mode) + prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "mmc", 25); + + old_mode = new_mode; + + schedule_delayed_work(&work_mmc, + msecs_to_jiffies(PERF_MMC_PROBE_DELAY)); + +} +#endif /* CONFIG_MMC_BLOCK */ + +static int __init performance_register(void) +{ + int ret; + +#ifdef CONFIG_MMC_BLOCK + ret = prcmu_qos_add_requirement(PRCMU_QOS_ARM_OPP, "mmc", 25); + if (ret) { + pr_err("%s: Failed to add PRCMU req for mmc\n", __func__); + goto out; + } + + INIT_DELAYED_WORK_DEFERRABLE(&work_mmc, mmc_load); + + schedule_delayed_work(&work_mmc, + msecs_to_jiffies(PERF_MMC_PROBE_DELAY)); +#endif + + ret = prcmu_qos_add_requirement(PRCMU_QOS_ARM_OPP, "wlan", 25); + if (ret) { + pr_err("%s: Failed to add PRCMU req for wlan\n", __func__); + goto out; + } + + INIT_DELAYED_WORK_DEFERRABLE(&work_wlan_workaround, + wlan_load); + + schedule_delayed_work_on(0, &work_wlan_workaround, + msecs_to_jiffies(WLAN_PROBE_DELAY)); +out: + return ret; +} +late_initcall(performance_register); diff --git a/arch/arm/mach-ux500/pm/pm.c b/arch/arm/mach-ux500/pm/pm.c new file mode 100644 index 00000000000..880e9763a0f --- /dev/null +++ b/arch/arm/mach-ux500/pm/pm.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Rickard Andersson <rickard.andersson@stericsson.com> for + * ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#include <linux/io.h> +#include <linux/percpu.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/gpio/nomadik.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include <asm/hardware/gic.h> +#include <asm/processor.h> + +#include <mach/hardware.h> +#include <mach/pm.h> + +#define STABILIZATION_TIME 30 /* us */ +#define GIC_FREEZE_DELAY 1 /* us */ + +#define PRCM_ARM_WFI_STANDBY_CPU0_WFI 0x8 +#define PRCM_ARM_WFI_STANDBY_CPU1_WFI 0x10 + +/* Dual A9 core interrupt management unit registers */ +#define PRCM_A9_MASK_REQ 0x328 +#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ 0x1 +#define PRCM_A9_MASK_ACK 0x32c + +#define PRCM_ARMITMSK31TO0 0x11c +#define PRCM_ARMITMSK63TO32 0x120 +#define PRCM_ARMITMSK95TO64 0x124 +#define PRCM_ARMITMSK127TO96 0x128 +#define PRCM_POWER_STATE_VAL 0x25C +#define PRCM_ARMITVAL31TO0 0x260 +#define PRCM_ARMITVAL63TO32 0x264 +#define PRCM_ARMITVAL95TO64 0x268 +#define PRCM_ARMITVAL127TO96 0x26C + +/* ARM WFI Standby signal register */ +#define PRCM_ARM_WFI_STANDBY 0x130 + +/* IO force */ +#define PRCM_IOCR 0x310 +#define PRCM_IOCR_IOFORCE 0x1 +#ifdef CONFIG_UX500_SUSPEND_DBG_WAKE_ON_UART +int ux500_console_uart_gpio_pin = CONFIG_UX500_CONSOLE_UART_GPIO_PIN; +#endif +static u32 u8500_gpio_banks[] = {U8500_GPIOBANK0_BASE, + U8500_GPIOBANK1_BASE, + U8500_GPIOBANK2_BASE, + U8500_GPIOBANK3_BASE, + U8500_GPIOBANK4_BASE, + U8500_GPIOBANK5_BASE, + U8500_GPIOBANK6_BASE, + U8500_GPIOBANK7_BASE, + U8500_GPIOBANK8_BASE}; + +static u32 u5500_gpio_banks[] = {U5500_GPIOBANK0_BASE, + U5500_GPIOBANK1_BASE, + U5500_GPIOBANK2_BASE, + U5500_GPIOBANK3_BASE, + U5500_GPIOBANK4_BASE, + U5500_GPIOBANK5_BASE, + U5500_GPIOBANK6_BASE, + U5500_GPIOBANK7_BASE}; + +static u32 ux500_gpio_wks[ARRAY_SIZE(u8500_gpio_banks)]; + +inline int ux500_pm_arm_on_ext_clk(bool leave_arm_pll_on) +{ + return 0; +} + +/* Decouple GIC from the interrupt bus */ +void ux500_pm_gic_decouple(void) +{ + prcmu_write_masked(PRCM_A9_MASK_REQ, + PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ, + PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ); + + (void)prcmu_read(PRCM_A9_MASK_REQ); + + /* TODO: Use the ack bit when possible */ + udelay(GIC_FREEZE_DELAY); /* Wait for the GIC to freeze */ +} + +/* Recouple GIC with the interrupt bus */ +void ux500_pm_gic_recouple(void) +{ + prcmu_write_masked(PRCM_A9_MASK_REQ, + PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ, + 0); + + /* TODO: Use the ack bit when possible */ +} + +#define GIC_NUMBER_REGS 5 +bool ux500_pm_gic_pending_interrupt(void) +{ + u32 pr; /* Pending register */ + u32 er; /* Enable register */ + int i; + + /* 5 registers. STI & PPI not skipped */ + for (i = 0; i < GIC_NUMBER_REGS; i++) { + + pr = readl_relaxed(__io_address(U8500_GIC_DIST_BASE) + + GIC_DIST_PENDING_SET + i * 4); + er = readl_relaxed(__io_address(U8500_GIC_DIST_BASE) + + GIC_DIST_ENABLE_SET + i * 4); + + if (pr & er) + return true; /* There is a pending interrupt */ + } + return false; +} + +#define GIC_NUMBER_SPI_REGS 4 +bool ux500_pm_prcmu_pending_interrupt(void) +{ + u32 it; + u32 im; + int i; + + for (i = 0; i < GIC_NUMBER_SPI_REGS; i++) { /* There are 4 registers */ + + it = prcmu_read(PRCM_ARMITVAL31TO0 + i * 4); + im = prcmu_read(PRCM_ARMITMSK31TO0 + i * 4); + + if (it & im) + return true; /* There is a pending interrupt */ + } + + return false; +} + +void ux500_pm_prcmu_set_ioforce(bool enable) +{ + if (enable) + prcmu_write_masked(PRCM_IOCR, + PRCM_IOCR_IOFORCE, + PRCM_IOCR_IOFORCE); + else + prcmu_write_masked(PRCM_IOCR, + PRCM_IOCR_IOFORCE, + 0); +} + +void ux500_pm_prcmu_copy_gic_settings(void) +{ + u32 er; /* Enable register */ + int i; + + for (i = 0; i < GIC_NUMBER_SPI_REGS; i++) { /* 4*32 SPI interrupts */ + /* +1 due to skip STI and PPI */ + er = readl_relaxed(__io_address(U8500_GIC_DIST_BASE) + + GIC_DIST_ENABLE_SET + (i + 1) * 4); + prcmu_write(PRCM_ARMITMSK31TO0 + i * 4, er); + } +} + +void ux500_pm_gpio_save_wake_up_status(void) +{ + int num_banks; + u32 *banks; + int i; + + if (cpu_is_u5500()) { + num_banks = ARRAY_SIZE(u5500_gpio_banks); + banks = u5500_gpio_banks; + } else { + num_banks = ARRAY_SIZE(u8500_gpio_banks); + banks = u8500_gpio_banks; + } + + nmk_gpio_clocks_enable(); + + for (i = 0; i < num_banks; i++) + ux500_gpio_wks[i] = readl(__io_address(banks[i]) + NMK_GPIO_WKS); + + nmk_gpio_clocks_disable(); +} + +u32 ux500_pm_gpio_read_wake_up_status(unsigned int bank_num) +{ + if (WARN_ON(cpu_is_u5500() && bank_num >= + ARRAY_SIZE(u5500_gpio_banks))) + return 0; + + if (WARN_ON(cpu_is_u8500() && bank_num >= + ARRAY_SIZE(u8500_gpio_banks))) + return 0; + + return ux500_gpio_wks[bank_num]; +} + +/* Check if the other CPU is in WFI */ +bool ux500_pm_other_cpu_wfi(void) +{ + if (smp_processor_id()) { + /* We are CPU 1 => check if CPU0 is in WFI */ + if (prcmu_read(PRCM_ARM_WFI_STANDBY) & + PRCM_ARM_WFI_STANDBY_CPU0_WFI) + return true; + } else { + /* We are CPU 0 => check if CPU1 is in WFI */ + if (prcmu_read(PRCM_ARM_WFI_STANDBY) & + PRCM_ARM_WFI_STANDBY_CPU1_WFI) + return true; + } + + return false; +} diff --git a/arch/arm/mach-ux500/pm/prcmu-qos-power.c b/arch/arm/mach-ux500/pm/prcmu-qos-power.c new file mode 100644 index 00000000000..3bd99b766af --- /dev/null +++ b/arch/arm/mach-ux500/pm/prcmu-qos-power.c @@ -0,0 +1,711 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * Author: Martin Persson + * Per Fransson <per.xx.fransson@stericsson.com> + * + * Quality of Service for the U8500 PRCM Unit interface driver + * + * Strongly influenced by kernel/pm_qos_params.c. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <linux/uaccess.h> +#include <linux/cpufreq.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <linux/cpufreq-dbx500.h> + +#include <mach/prcmu-debug.h> + +#define ARM_THRESHOLD_FREQ (400000) + +static int qos_delayed_cpufreq_notifier(struct notifier_block *, + unsigned long, void *); + +static s32 cpufreq_requirement_queued; +static s32 cpufreq_requirement_set; + +/* + * locking rule: all changes to requirements or prcmu_qos_object list + * and prcmu_qos_objects need to happen with prcmu_qos_lock + * held, taken with _irqsave. One lock to rule them all + */ +struct requirement_list { + struct list_head list; + union { + s32 value; + s32 usec; + s32 kbps; + }; + char *name; +}; + +static s32 max_compare(s32 v1, s32 v2); + +struct prcmu_qos_object { + struct requirement_list requirements; + struct blocking_notifier_head *notifiers; + struct miscdevice prcmu_qos_power_miscdev; + char *name; + s32 default_value; + s32 force_value; + atomic_t target_value; + s32 (*comparitor)(s32, s32); +}; + +static struct prcmu_qos_object null_qos; +static BLOCKING_NOTIFIER_HEAD(prcmu_ape_opp_notifier); +static BLOCKING_NOTIFIER_HEAD(prcmu_ddr_opp_notifier); + +static struct prcmu_qos_object ape_opp_qos = { + .requirements = { + LIST_HEAD_INIT(ape_opp_qos.requirements.list) + }, + .notifiers = &prcmu_ape_opp_notifier, + .name = "ape_opp", + /* Target value in % APE OPP */ + .default_value = 50, + .force_value = 0, + .target_value = ATOMIC_INIT(50), + .comparitor = max_compare +}; + +static struct prcmu_qos_object ddr_opp_qos = { + .requirements = { + LIST_HEAD_INIT(ddr_opp_qos.requirements.list) + }, + .notifiers = &prcmu_ddr_opp_notifier, + .name = "ddr_opp", + /* Target value in % DDR OPP */ + .default_value = 25, + .force_value = 0, + .target_value = ATOMIC_INIT(25), + .comparitor = max_compare +}; + +static struct prcmu_qos_object arm_opp_qos = { + .requirements = { + LIST_HEAD_INIT(arm_opp_qos.requirements.list) + }, + /* + * No notifier on ARM opp qos request, since this won't actually + * do anything, except changing limits for cpufreq + */ + .name = "arm_opp", + /* Target value in % ARM OPP, note can be 125% */ + .default_value = 25, + .force_value = 0, + .target_value = ATOMIC_INIT(25), + .comparitor = max_compare +}; + +static struct prcmu_qos_object *prcmu_qos_array[] = { + &null_qos, + &ape_opp_qos, + &ddr_opp_qos, + &arm_opp_qos, +}; + +static DEFINE_MUTEX(prcmu_qos_mutex); +static DEFINE_SPINLOCK(prcmu_qos_lock); + +static bool ape_opp_50_partly_25_enabled; + +static unsigned long cpufreq_opp_delay = HZ / 5; + +unsigned long prcmu_qos_get_cpufreq_opp_delay(void) +{ + return cpufreq_opp_delay; +} + +static struct notifier_block qos_delayed_cpufreq_notifier_block = { + .notifier_call = qos_delayed_cpufreq_notifier, +}; + +void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) +{ + if (n == 0) { + cpufreq_unregister_notifier(&qos_delayed_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + prcmu_qos_update_requirement(PRCMU_QOS_DDR_OPP, "cpufreq", + PRCMU_QOS_DEFAULT_VALUE); + prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, "cpufreq", + PRCMU_QOS_DEFAULT_VALUE); + cpufreq_requirement_set = PRCMU_QOS_DEFAULT_VALUE; + cpufreq_requirement_queued = PRCMU_QOS_DEFAULT_VALUE; + } else if (cpufreq_opp_delay != 0) { + cpufreq_register_notifier(&qos_delayed_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + } + cpufreq_opp_delay = n; +} +#ifdef CONFIG_CPU_FREQ +static void update_cpu_limits(s32 extreme_value) +{ + int cpu; + struct cpufreq_policy policy; + int ret; + int min_freq, max_freq; + + for_each_online_cpu(cpu) { + ret = cpufreq_get_policy(&policy, cpu); + if (ret) { + pr_err("prcmu qos: get cpufreq policy failed (cpu%d)\n", + cpu); + continue; + } + + ret = dbx500_cpufreq_get_limits(cpu, extreme_value, + &min_freq, &max_freq); + if (ret) + continue; + /* + * cpufreq fw does not allow frequency change if + * "current min freq" > "new max freq" or + * "current max freq" < "new min freq". + * Thus the intermediate steps below. + */ + if (policy.min > max_freq) { + ret = cpufreq_update_freq(cpu, min_freq, policy.max); + if (ret) + pr_err("prcmu qos: update min cpufreq failed (1)\n"); + } + if (policy.max < min_freq) { + ret = cpufreq_update_freq(cpu, policy.min, max_freq); + if (ret) + pr_err("prcmu qos: update max cpufreq failed (2)\n"); + } + + ret = cpufreq_update_freq(cpu, min_freq, max_freq); + if (ret) + pr_err("prcmu qos: update max cpufreq failed (3)\n"); + } + +} +#else +static inline void update_cpu_limits(s32 extreme_value) { } +#endif +/* static helper function */ +static s32 max_compare(s32 v1, s32 v2) +{ + return max(v1, v2); +} + +static void update_target(int target) +{ + s32 extreme_value; + struct requirement_list *node; + unsigned long flags; + bool update = false; + u8 op; + + mutex_lock(&prcmu_qos_mutex); + + spin_lock_irqsave(&prcmu_qos_lock, flags); + extreme_value = prcmu_qos_array[target]->default_value; + + if (prcmu_qos_array[target]->force_value != 0) { + extreme_value = prcmu_qos_array[target]->force_value; + update = true; + } else { + list_for_each_entry(node, + &prcmu_qos_array[target]->requirements.list, + list) { + extreme_value = prcmu_qos_array[target]->comparitor( + extreme_value, node->value); + } + if (atomic_read(&prcmu_qos_array[target]->target_value) + != extreme_value) { + update = true; + atomic_set(&prcmu_qos_array[target]->target_value, + extreme_value); + pr_debug("prcmu qos: new target for qos %d is %d\n", + target, atomic_read( + &prcmu_qos_array[target]->target_value + )); + } + } + + spin_unlock_irqrestore(&prcmu_qos_lock, flags); + + if (!update) + goto unlock_and_return; + + if (prcmu_qos_array[target]->notifiers) + blocking_notifier_call_chain(prcmu_qos_array[target]->notifiers, + (unsigned long)extreme_value, + NULL); + switch (target) { + case PRCMU_QOS_DDR_OPP: + switch (extreme_value) { + case 50: + op = DDR_50_OPP; + pr_debug("prcmu qos: set ddr opp to 50%%\n"); + break; + case 100: + op = DDR_100_OPP; + pr_debug("prcmu qos: set ddr opp to 100%%\n"); + break; + case 25: + /* 25% DDR OPP is not supported on 5500 */ + if (!cpu_is_u5500()) { + op = DDR_25_OPP; + pr_debug("prcmu qos: set ddr opp to 25%%\n"); + break; + } + default: + pr_err("prcmu qos: Incorrect ddr target value (%d)", + extreme_value); + goto unlock_and_return; + } + prcmu_set_ddr_opp(op); + prcmu_debug_ddr_opp_log(op); + break; + case PRCMU_QOS_APE_OPP: + switch (extreme_value) { + case 50: + if (ape_opp_50_partly_25_enabled) + op = APE_50_PARTLY_25_OPP; + else + op = APE_50_OPP; + pr_debug("prcmu qos: set ape opp to 50%%\n"); + break; + case 100: + op = APE_100_OPP; + pr_debug("prcmu qos: set ape opp to 100%%\n"); + break; + default: + pr_err("prcmu qos: Incorrect ape target value (%d)", + extreme_value); + goto unlock_and_return; + } + (void)prcmu_set_ape_opp(op); + prcmu_debug_ape_opp_log(op); + break; + case PRCMU_QOS_ARM_OPP: + { + mutex_unlock(&prcmu_qos_mutex); + /* + * We can't hold the mutex since changing cpufreq + * will trigger an prcmu fw callback. + */ + update_cpu_limits(extreme_value); + /* Return since the lock is unlocked */ + return; + + break; + } + default: + pr_err("prcmu qos: Incorrect target\n"); + break; + } + +unlock_and_return: + mutex_unlock(&prcmu_qos_mutex); +} + +void prcmu_qos_force_opp(int prcmu_qos_class, s32 i) +{ + prcmu_qos_array[prcmu_qos_class]->force_value = i; + update_target(prcmu_qos_class); +} + +void prcmu_qos_voice_call_override(bool enable) +{ + int ape_opp; + + mutex_lock(&prcmu_qos_mutex); + + ape_opp_50_partly_25_enabled = enable; + + ape_opp = prcmu_get_ape_opp(); + + if (ape_opp == APE_50_OPP) { + if (enable) + prcmu_set_ape_opp(APE_50_PARTLY_25_OPP); + else + prcmu_set_ape_opp(APE_50_OPP); + } + + mutex_unlock(&prcmu_qos_mutex); +} + +/** + * prcmu_qos_requirement - returns current prcmu qos expectation + * @prcmu_qos_class: identification of which qos value is requested + * + * This function returns the current target value in an atomic manner. + */ +int prcmu_qos_requirement(int prcmu_qos_class) +{ + return atomic_read(&prcmu_qos_array[prcmu_qos_class]->target_value); +} +EXPORT_SYMBOL_GPL(prcmu_qos_requirement); + +/** + * prcmu_qos_add_requirement - inserts new qos request into the list + * @prcmu_qos_class: identifies which list of qos request to us + * @name: identifies the request + * @value: defines the qos request + * + * This function inserts a new entry in the prcmu_qos_class list of requested + * qos performance characteristics. It recomputes the aggregate QoS + * expectations for the prcmu_qos_class of parameters. + */ +int prcmu_qos_add_requirement(int prcmu_qos_class, char *name, s32 value) +{ + struct requirement_list *dep; + unsigned long flags; + + dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL); + if (dep == NULL) + return -ENOMEM; + + if (value == PRCMU_QOS_DEFAULT_VALUE) + dep->value = prcmu_qos_array[prcmu_qos_class]->default_value; + else + dep->value = value; + dep->name = kstrdup(name, GFP_KERNEL); + if (!dep->name) + goto cleanup; + + spin_lock_irqsave(&prcmu_qos_lock, flags); + list_add(&dep->list, + &prcmu_qos_array[prcmu_qos_class]->requirements.list); + spin_unlock_irqrestore(&prcmu_qos_lock, flags); + update_target(prcmu_qos_class); + + return 0; + +cleanup: + kfree(dep); + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(prcmu_qos_add_requirement); + +/** + * prcmu_qos_update_requirement - modifies an existing qos request + * @prcmu_qos_class: identifies which list of qos request to us + * @name: identifies the request + * @value: defines the qos request + * + * Updates an existing qos requirement for the prcmu_qos_class of parameters + * along with updating the target prcmu_qos_class value. + * + * If the named request isn't in the list then no change is made. + */ +int prcmu_qos_update_requirement(int prcmu_qos_class, char *name, s32 new_value) +{ + unsigned long flags; + struct requirement_list *node; + int pending_update = 0; + + spin_lock_irqsave(&prcmu_qos_lock, flags); + list_for_each_entry(node, + &prcmu_qos_array[prcmu_qos_class]->requirements.list, list) { + if (strcmp(node->name, name) == 0) { + if (new_value == PRCMU_QOS_DEFAULT_VALUE) + node->value = + prcmu_qos_array[prcmu_qos_class]->default_value; + else + node->value = new_value; + pending_update = 1; + break; + } + } + spin_unlock_irqrestore(&prcmu_qos_lock, flags); + if (pending_update) + update_target(prcmu_qos_class); + + return 0; +} +EXPORT_SYMBOL_GPL(prcmu_qos_update_requirement); + +/** + * prcmu_qos_remove_requirement - modifies an existing qos request + * @prcmu_qos_class: identifies which list of qos request to us + * @name: identifies the request + * + * Will remove named qos request from prcmu_qos_class list of parameters and + * recompute the current target value for the prcmu_qos_class. + */ +void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) +{ + unsigned long flags; + struct requirement_list *node; + int pending_update = 0; + + spin_lock_irqsave(&prcmu_qos_lock, flags); + list_for_each_entry(node, + &prcmu_qos_array[prcmu_qos_class]->requirements.list, list) { + if (strcmp(node->name, name) == 0) { + kfree(node->name); + list_del(&node->list); + kfree(node); + pending_update = 1; + break; + } + } + spin_unlock_irqrestore(&prcmu_qos_lock, flags); + if (pending_update) + update_target(prcmu_qos_class); +} +EXPORT_SYMBOL_GPL(prcmu_qos_remove_requirement); + +/** + * prcmu_qos_add_notifier - sets notification entry for changes to target value + * @prcmu_qos_class: identifies which qos target changes should be notified. + * @notifier: notifier block managed by caller. + * + * will register the notifier into a notification chain that gets called + * upon changes to the prcmu_qos_class target value. + */ +int prcmu_qos_add_notifier(int prcmu_qos_class, struct notifier_block *notifier) +{ + int retval = -EINVAL; + + if (prcmu_qos_array[prcmu_qos_class]->notifiers) + retval = blocking_notifier_chain_register( + prcmu_qos_array[prcmu_qos_class]->notifiers, notifier); + + return retval; +} +EXPORT_SYMBOL_GPL(prcmu_qos_add_notifier); + +/** + * prcmu_qos_remove_notifier - deletes notification entry from chain. + * @prcmu_qos_class: identifies which qos target changes are notified. + * @notifier: notifier block to be removed. + * + * will remove the notifier from the notification chain that gets called + * upon changes to the prcmu_qos_class target value. + */ +int prcmu_qos_remove_notifier(int prcmu_qos_class, + struct notifier_block *notifier) +{ + int retval = -EINVAL; + if (prcmu_qos_array[prcmu_qos_class]->notifiers) + retval = blocking_notifier_chain_unregister( + prcmu_qos_array[prcmu_qos_class]->notifiers, notifier); + + return retval; +} +EXPORT_SYMBOL_GPL(prcmu_qos_remove_notifier); + +#define USER_QOS_NAME_LEN 32 + +static int prcmu_qos_power_open(struct inode *inode, struct file *filp, + long prcmu_qos_class) +{ + int ret; + char name[USER_QOS_NAME_LEN]; + + filp->private_data = (void *)prcmu_qos_class; + snprintf(name, USER_QOS_NAME_LEN, "file_%08x", (unsigned int)filp); + ret = prcmu_qos_add_requirement(prcmu_qos_class, name, + PRCMU_QOS_DEFAULT_VALUE); + if (ret >= 0) + return 0; + + return -EPERM; +} + + +static int prcmu_qos_ape_power_open(struct inode *inode, struct file *filp) +{ + return prcmu_qos_power_open(inode, filp, PRCMU_QOS_APE_OPP); +} + +static int prcmu_qos_ddr_power_open(struct inode *inode, struct file *filp) +{ + return prcmu_qos_power_open(inode, filp, PRCMU_QOS_DDR_OPP); +} + +static int prcmu_qos_arm_power_open(struct inode *inode, struct file *filp) +{ + return prcmu_qos_power_open(inode, filp, PRCMU_QOS_ARM_OPP); +} + +static int prcmu_qos_power_release(struct inode *inode, struct file *filp) +{ + int prcmu_qos_class; + char name[USER_QOS_NAME_LEN]; + + prcmu_qos_class = (long)filp->private_data; + snprintf(name, USER_QOS_NAME_LEN, "file_%08x", (unsigned int)filp); + prcmu_qos_remove_requirement(prcmu_qos_class, name); + + return 0; +} + +static ssize_t prcmu_qos_power_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + s32 value; + int prcmu_qos_class; + char name[USER_QOS_NAME_LEN]; + + prcmu_qos_class = (long)filp->private_data; + if (count != sizeof(s32)) + return -EINVAL; + if (copy_from_user(&value, buf, sizeof(s32))) + return -EFAULT; + snprintf(name, USER_QOS_NAME_LEN, "file_%08x", (unsigned int)filp); + prcmu_qos_update_requirement(prcmu_qos_class, name, value); + + return sizeof(s32); +} + +/* Functions to provide QoS to user space */ +static const struct file_operations prcmu_qos_ape_power_fops = { + .write = prcmu_qos_power_write, + .open = prcmu_qos_ape_power_open, + .release = prcmu_qos_power_release, +}; + +/* Functions to provide QoS to user space */ +static const struct file_operations prcmu_qos_ddr_power_fops = { + .write = prcmu_qos_power_write, + .open = prcmu_qos_ddr_power_open, + .release = prcmu_qos_power_release, +}; + +static const struct file_operations prcmu_qos_arm_power_fops = { + .write = prcmu_qos_power_write, + .open = prcmu_qos_arm_power_open, + .release = prcmu_qos_power_release, +}; + +static int register_prcmu_qos_misc(struct prcmu_qos_object *qos, + const struct file_operations *fops) +{ + qos->prcmu_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; + qos->prcmu_qos_power_miscdev.name = qos->name; + qos->prcmu_qos_power_miscdev.fops = fops; + + return misc_register(&qos->prcmu_qos_power_miscdev); +} + +static void qos_delayed_work_up_fn(struct work_struct *work) +{ + prcmu_qos_update_requirement(PRCMU_QOS_DDR_OPP, "cpufreq", 100); + prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, "cpufreq", 100); + cpufreq_requirement_set = 100; +} + +static void qos_delayed_work_down_fn(struct work_struct *work) +{ + prcmu_qos_update_requirement(PRCMU_QOS_DDR_OPP, "cpufreq", + PRCMU_QOS_DEFAULT_VALUE); + prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, "cpufreq", + PRCMU_QOS_DEFAULT_VALUE); + cpufreq_requirement_set = PRCMU_QOS_DEFAULT_VALUE; +} + +static DECLARE_DELAYED_WORK(qos_delayed_work_up, qos_delayed_work_up_fn); +static DECLARE_DELAYED_WORK(qos_delayed_work_down, qos_delayed_work_down_fn); + +static int qos_delayed_cpufreq_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct cpufreq_freqs *freq = data; + s32 new_ddr_target; + + /* Only react once per transition and only for one core, e.g. core 0 */ + if (event != CPUFREQ_POSTCHANGE || freq->cpu != 0) + return 0; + + /* + * APE and DDR OPP are always handled together in this solution. + * Hence no need to check both DDR and APE opp in the code below. + */ + + /* Which DDR OPP are we aiming for? */ + if (freq->new > ARM_THRESHOLD_FREQ) + new_ddr_target = 100; + else + new_ddr_target = PRCMU_QOS_DEFAULT_VALUE; + + if (new_ddr_target == cpufreq_requirement_queued) { + /* + * We're already at, or going to, the target requirement. + * This is only a fluctuation within the interval + * corresponding to the same DDR requirement. + */ + return 0; + } + cpufreq_requirement_queued = new_ddr_target; + + if (freq->new > ARM_THRESHOLD_FREQ) { + cancel_delayed_work_sync(&qos_delayed_work_down); + /* + * Only schedule this requirement if it is not the current + * one. + */ + if (new_ddr_target != cpufreq_requirement_set) + schedule_delayed_work(&qos_delayed_work_up, + cpufreq_opp_delay); + } else { + cancel_delayed_work_sync(&qos_delayed_work_up); + /* + * Only schedule this requirement if it is not the current + * one. + */ + if (new_ddr_target != cpufreq_requirement_set) + schedule_delayed_work(&qos_delayed_work_down, + cpufreq_opp_delay); + } + + return 0; +} + +static int __init prcmu_qos_power_init(void) +{ + int ret; + + /* 25% DDR OPP is not supported on u5500 */ + if (cpu_is_u5500()) { + ddr_opp_qos.default_value = 50; + atomic_set(&ddr_opp_qos.target_value, 50); + } + + ret = register_prcmu_qos_misc(&ape_opp_qos, &prcmu_qos_ape_power_fops); + if (ret < 0) { + pr_err("prcmu ape qos: setup failed\n"); + return ret; + } + + ret = register_prcmu_qos_misc(&ddr_opp_qos, &prcmu_qos_ddr_power_fops); + if (ret < 0) { + pr_err("prcmu ddr qos: setup failed\n"); + return ret; + } + + ret = register_prcmu_qos_misc(&arm_opp_qos, &prcmu_qos_arm_power_fops); + if (ret < 0) { + pr_err("prcmu arm qos: setup failed\n"); + return ret; + } + + prcmu_qos_add_requirement(PRCMU_QOS_DDR_OPP, "cpufreq", + PRCMU_QOS_DEFAULT_VALUE); + prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, "cpufreq", + PRCMU_QOS_DEFAULT_VALUE); + cpufreq_requirement_set = PRCMU_QOS_DEFAULT_VALUE; + cpufreq_requirement_queued = PRCMU_QOS_DEFAULT_VALUE; + + cpufreq_register_notifier(&qos_delayed_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + + return ret; +} + +late_initcall(prcmu_qos_power_init); diff --git a/arch/arm/mach-ux500/pm/runtime.c b/arch/arm/mach-ux500/pm/runtime.c new file mode 100644 index 00000000000..8608c43479e --- /dev/null +++ b/arch/arm/mach-ux500/pm/runtime.c @@ -0,0 +1,514 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Rabin Vincent <rabin.vincent@stericsson> for ST-Ericsson + * + * Based on: + * Runtime PM support code for SuperH Mobile ARM + * Copyright (C) 2009-2010 Magnus Damm + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/pm_runtime.h> +#include <linux/platform_device.h> +#include <linux/amba/bus.h> +#include <linux/regulator/dbx500-prcmu.h> +#include <linux/clk.h> +#include <linux/gfp.h> +#include <plat/pincfg.h> + +#include "../pins.h" + +#ifdef CONFIG_PM_RUNTIME +#define BIT_ONCE 0 +#define BIT_ACTIVE 1 +#define BIT_ENABLED 2 + +struct pm_runtime_data { + unsigned long flags; + struct ux500_regulator *regulator; + struct ux500_pins *pins; +}; + +static void __devres_release(struct device *dev, void *res) +{ + struct pm_runtime_data *prd = res; + + dev_dbg(dev, "__devres_release()\n"); + + if (test_bit(BIT_ENABLED, &prd->flags)) { + if (prd->pins) + ux500_pins_disable(prd->pins); + if (prd->regulator) + ux500_regulator_atomic_disable(prd->regulator); + } + + if (test_bit(BIT_ACTIVE, &prd->flags)) { + if (prd->pins) + ux500_pins_put(prd->pins); + if (prd->regulator) + ux500_regulator_put(prd->regulator); + } +} + +static struct pm_runtime_data *__to_prd(struct device *dev) +{ + return devres_find(dev, __devres_release, NULL, NULL); +} + +static void platform_pm_runtime_init(struct device *dev, + struct pm_runtime_data *prd) +{ + prd->pins = ux500_pins_get(dev_name(dev)); + + prd->regulator = ux500_regulator_get(dev); + if (IS_ERR(prd->regulator)) + prd->regulator = NULL; + + if (prd->pins || prd->regulator) { + dev_info(dev, "managed by runtime pm: %s%s\n", + prd->pins ? "pins " : "", + prd->regulator ? "regulator " : ""); + + set_bit(BIT_ACTIVE, &prd->flags); + } +} + +static void platform_pm_runtime_bug(struct device *dev, + struct pm_runtime_data *prd) +{ + if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) + dev_err(dev, "runtime pm suspend before resume\n"); +} + +static void platform_pm_runtime_used(struct device *dev, + struct pm_runtime_data *prd) +{ + if (prd) + set_bit(BIT_ONCE, &prd->flags); +} + +static int ux500_pd_runtime_idle(struct device *dev) +{ + return pm_runtime_suspend(dev); +} + +static void ux500_pd_disable(struct pm_runtime_data *prd) +{ + if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { + + if (prd->pins) + ux500_pins_disable(prd->pins); + + if (prd->regulator) + ux500_regulator_atomic_disable(prd->regulator); + + clear_bit(BIT_ENABLED, &prd->flags); + } +} + +static int ux500_pd_runtime_suspend(struct device *dev) +{ + int ret; + struct pm_runtime_data *prd = __to_prd(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + platform_pm_runtime_bug(dev, prd); + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ux500_pd_disable(prd); + + return 0; +} + +static void ux500_pd_enable(struct pm_runtime_data *prd) +{ + if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { + if (prd->pins) + ux500_pins_enable(prd->pins); + + if (prd->regulator) + ux500_regulator_atomic_enable(prd->regulator); + + set_bit(BIT_ENABLED, &prd->flags); + } +} + +static int ux500_pd_runtime_resume(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + platform_pm_runtime_used(dev, prd); + ux500_pd_enable(prd); + + return pm_generic_runtime_resume(dev); +} + +static int ux500_pd_suspend_noirq(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + /* Only handle devices that use runtime pm */ + if (!prd || !test_bit(BIT_ONCE, &prd->flags)) + return 0; + + /* Already is runtime suspended? Nothing to do. */ + if (pm_runtime_status_suspended(dev)) + return 0; + + /* + * We get here only if the device was not runtime suspended for some + * reason. We still need to do the power save stuff when going into + * suspend, so force it here. + */ + return ux500_pd_runtime_suspend(dev); +} + +static int ux500_pd_resume_noirq(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + /* Only handle devices that use runtime pm */ + if (!prd || !test_bit(BIT_ONCE, &prd->flags)) + return 0; + + /* + * Already was runtime suspended? No need to resume here, runtime + * resume will take care of it. + */ + if (pm_runtime_status_suspended(dev)) + return 0; + + /* + * We get here only if the device was not runtime suspended, + * but we forced it down in suspend_noirq above. Bring it + * up since pm-runtime thinks it is not suspended. + */ + return ux500_pd_runtime_resume(dev); +} +#ifdef CONFIG_UX500_SUSPEND +static int ux500_pd_amba_suspend_noirq(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + int (*callback)(struct device *) = NULL; + int ret = 0; + bool is_suspended = pm_runtime_status_suspended(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->suspend_noirq; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_suspend_noirq(dev); + + if (!ret && !is_suspended) + ux500_pd_disable(prd); + + return ret; +} + +static int ux500_pd_amba_resume_noirq(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + int (*callback)(struct device *) = NULL; + int ret = 0; + bool is_suspended = pm_runtime_status_suspended(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->resume_noirq; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_resume_noirq(dev); + + if (!ret && !is_suspended) + ux500_pd_enable(prd); + + return ret; +} +#else +static int ux500_pd_amba_suspend_noirq(struct device *dev) +{ + return 0; +} +static int ux500_pd_amba_resume_noirq(struct device *dev) +{ + return 0; +} +#endif +static int ux500_pd_amba_runtime_suspend(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + int (*callback)(struct device *) = NULL; + int ret; + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do this first, to make sure pins is not in undefined state after + * drivers has run their runtime suspend. This also means that drivers + * are not able to use their pins/regulators during runtime suspend. + */ + ux500_pd_disable(prd); + + /* + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->runtime_suspend; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_runtime_suspend(dev); + + if (ret) + ux500_pd_enable(prd); + + return ret; +} + +static int ux500_pd_amba_runtime_resume(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + int (*callback)(struct device *) = NULL; + int ret; + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->runtime_resume; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_runtime_resume(dev); + + /* + * Restore pins/regulator after drivers has runtime resumed, due + * to that we must not have pins in undefined state. This also means + * that drivers are not able to use their pins/regulators during + * runtime resume. + */ + if (!ret) + ux500_pd_enable(prd); + + return ret; +} + +static int ux500_pd_amba_runtime_idle(struct device *dev) +{ + int (*callback)(struct device *) = NULL; + int ret; + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do not bypass AMBA bus runtime functions by calling generic runtime + * directly. A future fix could be to implement a + * "pm_bus_generic_runtime_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->runtime_idle; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_runtime_idle(dev); + + return ret; +} + +static int ux500_pd_bus_notify(struct notifier_block *nb, + unsigned long action, + void *data, + bool enable) +{ + struct device *dev = data; + struct pm_runtime_data *prd; + + dev_dbg(dev, "%s() %ld !\n", __func__, action); + + if (action == BUS_NOTIFY_BIND_DRIVER) { + prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL); + if (prd) { + devres_add(dev, prd); + platform_pm_runtime_init(dev, prd); + if (enable) + ux500_pd_enable(prd); + } else + dev_err(dev, "unable to alloc memory for runtime pm\n"); + } + + return 0; +} + +static int ux500_pd_plat_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + return ux500_pd_bus_notify(nb, action, data, false); +} + +static int ux500_pd_amba_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + return ux500_pd_bus_notify(nb, action, data, true); +} + +#else /* CONFIG_PM_RUNTIME */ + +#define ux500_pd_suspend_noirq NULL +#define ux500_pd_resume_noirq NULL +#define ux500_pd_runtime_idle NULL +#define ux500_pd_runtime_suspend NULL +#define ux500_pd_runtime_resume NULL + +static int ux500_pd_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct ux500_regulator *regulator = NULL; + struct ux500_pins *pins = NULL; + struct device *dev = data; + const char *onoff = NULL; + + dev_dbg(dev, "%s() %ld !\n", __func__, action); + + switch (action) { + case BUS_NOTIFY_BIND_DRIVER: + pins = ux500_pins_get(dev_name(dev)); + if (pins) { + ux500_pins_enable(pins); + ux500_pins_put(pins); + } + + regulator = ux500_regulator_get(dev); + if (IS_ERR(regulator)) + regulator = NULL; + else { + ux500_regulator_atomic_enable(regulator); + ux500_regulator_put(regulator); + } + + onoff = "on"; + break; + case BUS_NOTIFY_UNBOUND_DRIVER: + pins = ux500_pins_get(dev_name(dev)); + if (pins) { + ux500_pins_disable(pins); + ux500_pins_put(pins); + } + + regulator = ux500_regulator_get(dev); + if (IS_ERR(regulator)) + regulator = NULL; + else { + ux500_regulator_atomic_disable(regulator); + ux500_regulator_put(regulator); + } + + onoff = "off"; + break; + } + + if (pins || regulator) { + dev_info(dev, "runtime pm disabled, forced %s: %s%s\n", + onoff, + pins ? "pins " : "", + regulator ? "regulator " : ""); + } + + return 0; +} + +#endif /* CONFIG_PM_RUNTIME */ + +struct dev_pm_domain ux500_amba_dev_power_domain = { + .ops = { + .suspend = amba_pm_suspend, + .resume = amba_pm_resume, + .freeze = amba_pm_freeze, + .thaw = amba_pm_thaw, + .poweroff = amba_pm_poweroff, + .restore = amba_pm_restore, + SET_RUNTIME_PM_OPS(ux500_pd_amba_runtime_suspend, + ux500_pd_amba_runtime_resume, + ux500_pd_amba_runtime_idle) + .suspend_noirq = ux500_pd_amba_suspend_noirq, + .resume_noirq = ux500_pd_amba_resume_noirq, + }, +}; + +struct dev_pm_domain ux500_dev_power_domain = { + .ops = { + SET_RUNTIME_PM_OPS(ux500_pd_runtime_suspend, + ux500_pd_runtime_resume, + ux500_pd_runtime_idle) + USE_PLATFORM_PM_SLEEP_OPS + .suspend_noirq = ux500_pd_suspend_noirq, + .resume_noirq = ux500_pd_resume_noirq, + }, +}; + +static struct notifier_block ux500_pd_platform_notifier = { + .notifier_call = ux500_pd_plat_bus_notify, +}; + +static struct notifier_block ux500_pd_amba_notifier = { + .notifier_call = ux500_pd_amba_bus_notify, +}; + +static int __init ux500_pm_runtime_platform_init(void) +{ + bus_register_notifier(&platform_bus_type, &ux500_pd_platform_notifier); + return 0; +} +core_initcall(ux500_pm_runtime_platform_init); + +/* + * The amba bus itself gets registered in a core_initcall, so we can't use + * that. + */ +static int __init ux500_pm_runtime_amba_init(void) +{ + bus_register_notifier(&amba_bustype, &ux500_pd_amba_notifier); + return 0; +} +arch_initcall(ux500_pm_runtime_amba_init); diff --git a/arch/arm/mach-ux500/pm/scu.h b/arch/arm/mach-ux500/pm/scu.h new file mode 100644 index 00000000000..a09e86a9d3c --- /dev/null +++ b/arch/arm/mach-ux500/pm/scu.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2009 ST-Ericsson SA + * + * 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. + */ + +#ifndef __ASMARM_ARCH_SCU_H +#define __ASMARM_ARCH_SCU_H + +#include <mach/hardware.h> + +#define SCU_BASE U8500_SCU_BASE +/* + * * SCU registers + * */ +#define SCU_CTRL 0x00 +#define SCU_CONFIG 0x04 +#define SCU_CPU_STATUS 0x08 +#define SCU_INVALIDATE 0x0c +#define SCU_FPGA_REVISION 0x10 + +#endif diff --git a/arch/arm/mach-ux500/pm/suspend.c b/arch/arm/mach-ux500/pm/suspend.c new file mode 100644 index 00000000000..df527964182 --- /dev/null +++ b/arch/arm/mach-ux500/pm/suspend.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * License Terms: GNU General Public License v2 + * + * Authors: Rickard Andersson <rickard.andersson@stericsson.com>, + * Jonas Aaberg <jonas.aberg@stericsson.com>, + * Sundar Iyer for ST-Ericsson. + */ + +#include <linux/suspend.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <linux/gpio/nomadik.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/ab8500-debug.h> +#include <linux/regulator/dbx500-prcmu.h> + +#include <mach/context.h> +#include <mach/pm.h> +#include <mach/id.h> + +#include "suspend_dbg.h" + +static void (*pins_suspend_force)(void); +static void (*pins_suspend_force_mux)(void); + +static suspend_state_t suspend_state = PM_SUSPEND_ON; + +void suspend_set_pins_force_fn(void (*force)(void), void (*force_mux)(void)) +{ + pins_suspend_force = force; + pins_suspend_force_mux = force_mux; +} + +static atomic_t block_sleep = ATOMIC_INIT(0); + +void suspend_block_sleep(void) +{ + atomic_inc(&block_sleep); +} + +void suspend_unblock_sleep(void) +{ + atomic_dec(&block_sleep); +} + +static bool sleep_is_blocked(void) +{ + return (atomic_read(&block_sleep) != 0); +} + +static int suspend(bool do_deepsleep) +{ + bool pins_force = pins_suspend_force_mux && pins_suspend_force; + int ret = 0; + + if (sleep_is_blocked()) { + pr_info("suspend/resume: interrupted by modem.\n"); + return -EBUSY; + } + + nmk_gpio_clocks_enable(); + + ux500_suspend_dbg_add_wake_on_uart(); + + nmk_gpio_wakeups_suspend(); + + /* configure the prcm for a sleep wakeup */ + if (cpu_is_u9500()) + prcmu_enable_wakeups(PRCMU_WAKEUP(ABB) | PRCMU_WAKEUP(HSI0)); + else +#if defined(CONFIG_RTC_DRV_PL031) + prcmu_enable_wakeups(PRCMU_WAKEUP(ABB) | PRCMU_WAKEUP(RTC)); +#else + prcmu_enable_wakeups(PRCMU_WAKEUP(ABB)); +#endif + + context_vape_save(); + + context_fsmc_save(); + + if (pins_force) { + /* + * Save GPIO settings before applying power save + * settings + */ + context_gpio_save(); + + /* Apply GPIO power save mux settings */ + context_gpio_mux_safe_switch(true); + pins_suspend_force_mux(); + context_gpio_mux_safe_switch(false); + + /* Apply GPIO power save settings */ + pins_suspend_force(); + } + + ux500_pm_gic_decouple(); + + if (ux500_pm_gic_pending_interrupt()) { + pr_info("suspend/resume: pending interrupt\n"); + + /* Recouple GIC with the interrupt bus */ + ux500_pm_gic_recouple(); + ret = -EBUSY; + + goto exit; + } + ux500_pm_prcmu_set_ioforce(true); + + if (do_deepsleep) { + context_varm_save_common(); + context_varm_save_core(); + context_gic_dist_disable_unneeded_irqs(); + context_save_cpu_registers(); + + /* + * Due to we have only 100us between requesting a powerstate + * and wfi, we clean the cache before as well to assure the + * final cache clean before wfi has as little as possible to + * do. + */ + context_clean_l1_cache_all(); + + (void) prcmu_set_power_state(PRCMU_AP_DEEP_SLEEP, + false, false); + context_save_to_sram_and_wfi(true); + + context_restore_cpu_registers(); + context_varm_restore_core(); + context_varm_restore_common(); + + } else { + + context_clean_l1_cache_all(); + (void) prcmu_set_power_state(APEXECUTE_TO_APSLEEP, + false, false); + dsb(); + __asm__ __volatile__("wfi\n\t" : : : "memory"); + } + + context_vape_restore(); + + context_fsmc_restore(); + + /* If GPIO woke us up then save the pins that caused the wake up */ + ux500_pm_gpio_save_wake_up_status(); + + ux500_suspend_dbg_sleep_status(do_deepsleep); + + /* APE was turned off, restore IO ring */ + ux500_pm_prcmu_set_ioforce(false); + +exit: + if (pins_force) { + /* Restore gpio settings */ + context_gpio_mux_safe_switch(true); + context_gpio_restore_mux(); + context_gpio_mux_safe_switch(false); + context_gpio_restore(); + } + + /* This is what cpuidle wants */ + if (cpu_is_u9500()) + prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | + PRCMU_WAKEUP(ABB) | PRCMU_WAKEUP(HSI0)); + else + prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | + PRCMU_WAKEUP(ABB)); + + nmk_gpio_wakeups_resume(); + + ux500_suspend_dbg_remove_wake_on_uart(); + + nmk_gpio_clocks_disable(); + + return ret; +} + +static int ux500_suspend_enter(suspend_state_t state) +{ + if (ux500_suspend_enabled()) { + if (ux500_suspend_deepsleep_enabled() && + state == PM_SUSPEND_MEM) + return suspend(true); + if (ux500_suspend_sleep_enabled()) + return suspend(false); + } + + ux500_suspend_dbg_add_wake_on_uart(); + /* + * Set IOFORCE in order to wake on GPIO the same way + * as in deeper sleep. + * (U5500 is not ready for IOFORCE) + */ + if (!cpu_is_u5500()) + ux500_pm_prcmu_set_ioforce(true); + + dsb(); + __asm__ __volatile__("wfi\n\t" : : : "memory"); + + if (!cpu_is_u5500()) + ux500_pm_prcmu_set_ioforce(false); + ux500_suspend_dbg_remove_wake_on_uart(); + + return 0; +} + +static int ux500_suspend_valid(suspend_state_t state) +{ + return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; +} + +static int ux500_suspend_prepare(void) +{ + int ret; + + ret = regulator_suspend_prepare(suspend_state); + if (ret < 0) + return ret; + + return 0; +} + +static int ux500_suspend_prepare_late(void) +{ + /* ESRAM to retention instead of OFF until ROM is fixed */ + (void) prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); + + ab8500_regulator_debug_force(); + ux500_regulator_suspend_debug(); + return 0; +} + +static void ux500_suspend_wake(void) +{ + ux500_regulator_resume_debug(); + ab8500_regulator_debug_restore(); + (void) prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); +} + +static void ux500_suspend_finish(void) +{ + (void)regulator_suspend_finish(); +} + +static int ux500_suspend_begin(suspend_state_t state) +{ + (void) prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "suspend", 125); + suspend_state = state; + return ux500_suspend_dbg_begin(state); +} + +static void ux500_suspend_end(void) +{ + (void) prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "suspend", 25); + suspend_state = PM_SUSPEND_ON; +} + +static struct platform_suspend_ops ux500_suspend_ops = { + .enter = ux500_suspend_enter, + .valid = ux500_suspend_valid, + .prepare = ux500_suspend_prepare, + .prepare_late = ux500_suspend_prepare_late, + .wake = ux500_suspend_wake, + .finish = ux500_suspend_finish, + .begin = ux500_suspend_begin, + .end = ux500_suspend_end, +}; + +static __init int ux500_suspend_init(void) +{ + ux500_suspend_dbg_init(); + prcmu_qos_add_requirement(PRCMU_QOS_ARM_OPP, "suspend", 25); + suspend_set_ops(&ux500_suspend_ops); + return 0; +} +device_initcall(ux500_suspend_init); diff --git a/arch/arm/mach-ux500/pm/suspend_dbg.c b/arch/arm/mach-ux500/pm/suspend_dbg.c new file mode 100644 index 00000000000..1b7d871ba52 --- /dev/null +++ b/arch/arm/mach-ux500/pm/suspend_dbg.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * License Terms: GNU General Public License v2 + * + * Author: Rickard Andersson <rickard.andersson@stericsson.com>, + * Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson + * + */ +#include <linux/kernel.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <linux/suspend.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/uaccess.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include <mach/pm.h> + +#ifdef CONFIG_UX500_SUSPEND_STANDBY +static u32 sleep_enabled = 1; +#else +static u32 sleep_enabled; +#endif + +#ifdef CONFIG_UX500_SUSPEND_MEM +static u32 deepsleep_enabled = 1; +#else +static u32 deepsleep_enabled; +#endif + +static u32 suspend_enabled = 1; + +static u32 deepsleeps_done; +static u32 deepsleeps_failed; +static u32 sleeps_done; +static u32 sleeps_failed; +static u32 suspend_count; + +#ifdef CONFIG_UX500_SUSPEND_DBG_WAKE_ON_UART +void ux500_suspend_dbg_add_wake_on_uart(void) +{ + irq_set_irq_wake(GPIO_TO_IRQ(ux500_console_uart_gpio_pin), 1); + irq_set_irq_type(GPIO_TO_IRQ(ux500_console_uart_gpio_pin), + IRQ_TYPE_EDGE_BOTH); +} + +void ux500_suspend_dbg_remove_wake_on_uart(void) +{ + irq_set_irq_wake(GPIO_TO_IRQ(ux500_console_uart_gpio_pin), 0); +} +#endif + +bool ux500_suspend_enabled(void) +{ + return suspend_enabled != 0; +} + +bool ux500_suspend_sleep_enabled(void) +{ + return sleep_enabled != 0; +} + +bool ux500_suspend_deepsleep_enabled(void) +{ + return deepsleep_enabled != 0; +} + +void ux500_suspend_dbg_sleep_status(bool is_deepsleep) +{ + enum prcmu_power_status prcmu_status; + + prcmu_status = prcmu_get_power_state_result(); + + if (is_deepsleep) { + pr_info("Returning from ApDeepSleep. PRCMU ret: 0x%x - %s\n", + prcmu_status, + prcmu_status == PRCMU_DEEP_SLEEP_OK ? + "Success" : "Fail!"); + if (prcmu_status == PRCMU_DEEP_SLEEP_OK) + deepsleeps_done++; + else + deepsleeps_failed++; + } else { + pr_info("Returning from ApSleep. PRCMU ret: 0x%x - %s\n", + prcmu_status, + prcmu_status == PRCMU_SLEEP_OK ? "Success" : "Fail!"); + if (prcmu_status == PRCMU_SLEEP_OK) + sleeps_done++; + else + sleeps_failed++; + } +} + +int ux500_suspend_dbg_begin(suspend_state_t state) +{ + suspend_count++; + return 0; +} + +void ux500_suspend_dbg_init(void) +{ + struct dentry *suspend_dir; + struct dentry *file; + + suspend_dir = debugfs_create_dir("suspend", NULL); + if (IS_ERR_OR_NULL(suspend_dir)) + return; + + file = debugfs_create_bool("sleep", S_IWUGO | S_IRUGO, + suspend_dir, + &sleep_enabled); + if (IS_ERR_OR_NULL(file)) + goto error; + + file = debugfs_create_bool("deepsleep", S_IWUGO | S_IRUGO, + suspend_dir, + &deepsleep_enabled); + if (IS_ERR_OR_NULL(file)) + goto error; + + file = debugfs_create_bool("enable", S_IWUGO | S_IRUGO, + suspend_dir, + &suspend_enabled); + if (IS_ERR_OR_NULL(file)) + goto error; + + file = debugfs_create_u32("count", S_IRUGO, + suspend_dir, + &suspend_count); + if (IS_ERR_OR_NULL(file)) + goto error; + + file = debugfs_create_u32("sleep_count", S_IRUGO, + suspend_dir, + &sleeps_done); + if (IS_ERR_OR_NULL(file)) + goto error; + + file = debugfs_create_u32("deepsleep_count", S_IRUGO, + suspend_dir, + &deepsleeps_done); + if (IS_ERR_OR_NULL(file)) + goto error; + + + file = debugfs_create_u32("sleep_failed", S_IRUGO, + suspend_dir, + &sleeps_failed); + if (IS_ERR_OR_NULL(file)) + goto error; + + file = debugfs_create_u32("deepsleep_failed", S_IRUGO, + suspend_dir, + &deepsleeps_failed); + if (IS_ERR_OR_NULL(file)) + goto error; + + return; +error: + if (!IS_ERR_OR_NULL(suspend_dir)) + debugfs_remove_recursive(suspend_dir); +} diff --git a/arch/arm/mach-ux500/pm/suspend_dbg.h b/arch/arm/mach-ux500/pm/suspend_dbg.h new file mode 100644 index 00000000000..29bfec7e269 --- /dev/null +++ b/arch/arm/mach-ux500/pm/suspend_dbg.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * License Terms: GNU General Public License v2 + * + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson + * + */ + +#ifndef UX500_SUSPEND_DBG_H +#define UX500_SUSPEND_DBG_H + +#include <linux/kernel.h> +#include <linux/suspend.h> + +#ifdef CONFIG_UX500_SUSPEND_DBG_WAKE_ON_UART +void ux500_suspend_dbg_add_wake_on_uart(void); +void ux500_suspend_dbg_remove_wake_on_uart(void); +#else +static inline void ux500_suspend_dbg_add_wake_on_uart(void) { } +static inline void ux500_suspend_dbg_remove_wake_on_uart(void) { } +#endif + +#ifdef CONFIG_UX500_SUSPEND_DBG +bool ux500_suspend_enabled(void); +bool ux500_suspend_sleep_enabled(void); +bool ux500_suspend_deepsleep_enabled(void); +void ux500_suspend_dbg_sleep_status(bool is_deepsleep); +void ux500_suspend_dbg_init(void); +int ux500_suspend_dbg_begin(suspend_state_t state); + +#else +static inline bool ux500_suspend_enabled(void) +{ + return true; +} +static inline bool ux500_suspend_sleep_enabled(void) +{ +#ifdef CONFIG_UX500_SUSPEND_STANDBY + return true; +#else + return false; +#endif +} +static inline bool ux500_suspend_deepsleep_enabled(void) +{ +#ifdef CONFIG_UX500_SUSPEND_MEM + return true; +#else + return false; +#endif +} +static inline void ux500_suspend_dbg_sleep_status(bool is_deepsleep) { } +static inline void ux500_suspend_dbg_init(void) { } + +static inline int ux500_suspend_dbg_begin(suspend_state_t state) +{ + return 0; +} + +#endif + +#endif diff --git a/arch/arm/mach-ux500/pm/timer.c b/arch/arm/mach-ux500/pm/timer.c new file mode 100644 index 00000000000..fc81c2c15ad --- /dev/null +++ b/arch/arm/mach-ux500/pm/timer.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2011 + * + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson + * + * License Terms: GNU General Public License v2 + * + * The RTC timer block is a ST Microelectronics variant of ARM PL031. + * Clockwatch part is the same as PL031, while the timer part is only + * present on the ST Microelectronics variant. + * Here only the timer part is used. + * + * The timer part is quite troublesome to program correctly. Lots + * of long delays must be there in order to secure that you actually get what + * you wrote. + * + * In other words, this timer is and should only used from cpuidle during + * special conditions when the surroundings are know in order to be able + * to remove the number of delays. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/ktime.h> +#include <linux/delay.h> + +#include <asm/errno.h> + +#include <mach/hardware.h> + +#define RTC_IMSC 0x10 +#define RTC_MIS 0x18 +#define RTC_ICR 0x1C +#define RTC_TDR 0x20 +#define RTC_TLR1 0x24 +#define RTC_TCR 0x28 + +#define RTC_TLR2 0x2C +#define RTC_TPR1 0x3C + +#define RTC_TCR_RTTOS (1 << 0) +#define RTC_TCR_RTTEN (1 << 1) +#define RTC_TCR_RTTSS (1 << 2) + +#define RTC_IMSC_TIMSC (1 << 1) +#define RTC_ICR_TIC (1 << 1) +#define RTC_MIS_RTCTMIS (1 << 1) + +#define RTC_TCR_RTTPS_2 (1 << 4) +#define RTC_TCR_RTTPS_3 (2 << 4) +#define RTC_TCR_RTTPS_4 (3 << 4) +#define RTC_TCR_RTTPS_5 (4 << 4) +#define RTC_TCR_RTTPS_6 (5 << 4) +#define RTC_TCR_RTTPS_7 (6 << 4) +#define RTC_TCR_RTTPS_8 (7 << 4) + +#define WRITE_DELAY 130 /* 4 cycles plus margin */ + +/* + * Count down measure point. It just have to be high to differ + * from scheduled values. + */ +#define MEASURE_VAL 0xffffffff + +/* Just a value bigger than any reason able scheduled timeout. */ +#define MEASURE_VAL_LIMIT 0xf0000000 + +#define TICKS_TO_NS(x) ((s64)x * 30518) +#define US_TO_TICKS(x) ((u32)((1000 * x) / 30518)) + +static void __iomem *rtc_base; +static bool measure_latency; + +#ifdef CONFIG_UX500_CPUIDLE_DEBUG + +/* + * The plan here is to be able to measure the ApSleep/ApDeepSleep exit latency + * by having a know timer pattern. + * The first entry in the pattern, LR1, is the value that the scheduler + * wants us to sleep. The second pattern in a high value, too large to be + * scheduled, so we can differ between a running scheduled value and a + * time measure value. + * When a RTT interrupt has occured, the block will automatically start + * to execute the measure value in LR2 and when the ARM is awake, it reads + * how far the RTT has decreased the value loaded from LR2 and from that + * calculate how long time it took to wake up. + */ +ktime_t u8500_rtc_exit_latency_get(void) +{ + u32 ticks; + + if (measure_latency) { + ticks = MEASURE_VAL - readl(rtc_base + RTC_TDR); + + /* + * Check if we are actually counting on a LR2 value. + * If not we have woken on another interrupt. + */ + if (ticks < MEASURE_VAL_LIMIT) { + /* convert 32 kHz ticks to ns */ + return ktime_set(0, TICKS_TO_NS(ticks)); + } + } + return ktime_set(0, 0); +} + +static void measure_latency_start(void) +{ + udelay(WRITE_DELAY); + /* + * Disable RTT and clean self-start due to we want to restart, + * not continue from current pattern. (See below) + */ + writel(0, rtc_base + RTC_TCR); + udelay(WRITE_DELAY); + + /* + * Program LR2 (load register two) to maximum value to ease + * identification of timer interrupt vs other. + */ + writel(MEASURE_VAL, rtc_base + RTC_TLR2); + /* + * Set Load Register execution pattern, bit clear + * means pick LR1, bit set means LR2 + * 0xfe, binary 11111110 means first do LR1 then do + * LR2 seven times + */ + writel(0xfe, rtc_base + RTC_TPR1); + + udelay(WRITE_DELAY); + + /* + * Enable self-start, plus a pattern of eight. + */ + writel(RTC_TCR_RTTSS | RTC_TCR_RTTPS_8, + rtc_base + RTC_TCR); + udelay(WRITE_DELAY); +} + +void ux500_rtcrtt_measure_latency(bool enable) +{ + if (enable) { + measure_latency_start(); + } else { + writel(RTC_TCR_RTTSS | RTC_TCR_RTTOS, rtc_base + RTC_TCR); + writel(RTC_ICR_TIC, rtc_base + RTC_ICR); + writel(RTC_IMSC_TIMSC, rtc_base + RTC_IMSC); + } + measure_latency = enable; +} +#else +static inline void measure_latency_start(void) { } +static inline void ux500_rtcrtt_measure_latency(bool enable) +{ + writel(RTC_TCR_RTTSS | RTC_TCR_RTTOS, rtc_base + RTC_TCR); + writel(RTC_ICR_TIC, rtc_base + RTC_ICR); + writel(RTC_IMSC_TIMSC, rtc_base + RTC_IMSC); +} +#endif + +void ux500_rtcrtt_off(void) +{ + if (measure_latency) { + measure_latency_start(); + } else { + /* Disable, self start and oneshot mode */ + writel(RTC_TCR_RTTSS | RTC_TCR_RTTOS, rtc_base + RTC_TCR); + + /* Clear eventual interrupts */ + if (readl(rtc_base + RTC_MIS) & RTC_MIS_RTCTMIS) + writel(RTC_ICR_TIC, rtc_base + RTC_ICR); + } +} + +void ux500_rtcrtt_next(u32 time_us) +{ + writel(US_TO_TICKS(time_us), rtc_base + RTC_TLR1); +} + +static int __init ux500_rtcrtt_init(void) +{ + if (cpu_is_u8500() || cpu_is_u9540()) { + rtc_base = __io_address(U8500_RTC_BASE); + } else if (cpu_is_u5500()) { + rtc_base = __io_address(U5500_RTC_BASE); + } else { + pr_err("timer-rtt: Unknown DB Asic!\n"); + return -EINVAL; + } + ux500_rtcrtt_measure_latency(false); + return 0; +} +subsys_initcall(ux500_rtcrtt_init); diff --git a/arch/arm/mach-ux500/pm/usecase_gov.c b/arch/arm/mach-ux500/pm/usecase_gov.c new file mode 100644 index 00000000000..1fd4fbb9830 --- /dev/null +++ b/arch/arm/mach-ux500/pm/usecase_gov.c @@ -0,0 +1,962 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Alexandre Torgue <alexandre.torgue@stericsson.com> for ST-Ericsson + * Author: Vincent Guittot <vincent.guittot@stericsson.com> for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/io.h> +#include <linux/earlysuspend.h> +#include <linux/cpu.h> +#include <linux/sched.h> +#include <linux/tick.h> +#include <linux/workqueue.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/uaccess.h> +#include <linux/kernel_stat.h> +#include <linux/ktime.h> +#include <linux/cpufreq.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <linux/cpufreq-dbx500.h> + +#include "../../../../drivers/cpuidle/cpuidle-dbx500.h" + + +#define CPULOAD_MEAS_DELAY 3000 /* 3 secondes of delta */ + +/* debug */ +static unsigned long debug; + +#define hp_printk \ + if (debug) \ + printk \ + +enum ux500_uc { + UX500_UC_NORMAL = 0, + UX500_UC_AUTO, /* Add use case below this. */ + UX500_UC_VC, + UX500_UC_LPA, + UX500_UC_USER, /* Add use case above this. */ + UX500_UC_MAX, +}; + +/* cpu load monitor struct */ +#define LOAD_MONITOR 4 +struct hotplug_cpu_info { + cputime64_t prev_cpu_wall; + cputime64_t prev_cpu_idle; + cputime64_t prev_cpu_io; + unsigned int load[LOAD_MONITOR]; + unsigned int idx; +}; + +static DEFINE_PER_CPU(struct hotplug_cpu_info, hotplug_info); + +/* Auto trigger criteria */ +/* loadavg threshold */ +static unsigned long lower_threshold = 175; +static unsigned long upper_threshold = 450; +/* load balancing */ +static unsigned long max_unbalance = 210; +/* trend load */ +static unsigned long trend_unbalance = 40; +static unsigned long min_trend = 5; +/* instant load */ +static unsigned long max_instant = 85; + +/* Number of interrupts per second before exiting auto mode */ +static u32 exit_irq_per_s = 1000; +static u64 old_num_irqs; + +static DEFINE_MUTEX(usecase_mutex); +static DEFINE_MUTEX(state_mutex); +static bool user_config_updated; +static enum ux500_uc current_uc = UX500_UC_MAX; +static bool is_work_scheduled; +static bool is_early_suspend; +static bool uc_master_enable = true; + +static unsigned int cpuidle_deepest_state; + +struct usecase_config { + char *name; + /* Minimum required ARM OPP. if no requirement set 25 */ + unsigned int min_arm_opp; + unsigned int max_arm_opp; + unsigned long cpuidle_multiplier; + bool second_cpu_online; + bool l2_prefetch_en; + bool enable; + unsigned int forced_state; /* Forced cpu idle state. */ + bool vc_override; /* QOS override for voice-call. */ +}; + +static struct usecase_config usecase_conf[UX500_UC_MAX] = { + [UX500_UC_NORMAL] = { + .name = "normal", + .min_arm_opp = 25, + .cpuidle_multiplier = 1024, + .second_cpu_online = true, + .l2_prefetch_en = true, + .enable = true, + .forced_state = 0, + .vc_override = false, + }, + [UX500_UC_AUTO] = { + .name = "auto", + .min_arm_opp = 25, + .cpuidle_multiplier = 0, + .second_cpu_online = false, + .l2_prefetch_en = true, + .enable = false, + .forced_state = 0, + .vc_override = false, + }, + [UX500_UC_VC] = { + .name = "voice-call", + .min_arm_opp = 50, + .cpuidle_multiplier = 0, + .second_cpu_online = true, + .l2_prefetch_en = false, + .enable = false, + .forced_state = 0, + .vc_override = true, + }, + [UX500_UC_LPA] = { + .name = "low-power-audio", + .min_arm_opp = 50, + .cpuidle_multiplier = 0, + .second_cpu_online = false, + .l2_prefetch_en = false, + .enable = false, + .forced_state = 0, /* Updated dynamically */ + .vc_override = false, + }, +}; + +/* daemon */ +static struct delayed_work work_usecase; +static struct early_suspend usecase_early_suspend; + +/* calculate loadavg */ +#define LOAD_INT(x) ((x) >> FSHIFT) +#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) + +extern int cpufreq_update_freq(int cpu, unsigned int min, unsigned int max); +extern int cpuidle_set_multiplier(unsigned int value); +extern int cpuidle_force_state(unsigned int state); + +static unsigned long determine_loadavg(void) +{ + unsigned long avg = 0; + unsigned long avnrun[3]; + + get_avenrun(avnrun, FIXED_1 / 200, 0); + avg += (LOAD_INT(avnrun[0]) * 100) + (LOAD_FRAC(avnrun[0]) % 100); + + return avg; +} + +static unsigned long determine_cpu_load(void) +{ + int i; + unsigned long total_load = 0; + + /* get cpu load of each cpu */ + for_each_online_cpu(i) { + unsigned int load; + unsigned int idle_time, wall_time; + cputime64_t cur_wall_time, cur_idle_time; + struct hotplug_cpu_info *info; + + info = &per_cpu(hotplug_info, i); + + /* update both cur_idle_time and cur_wall_time */ + cur_idle_time = get_cpu_idle_time_us(i, &cur_wall_time); + + /* how much wall time has passed since last iteration? */ + wall_time = (unsigned int) cputime64_sub(cur_wall_time, + info->prev_cpu_wall); + info->prev_cpu_wall = cur_wall_time; + + /* how much idle time has passed since last iteration? */ + idle_time = (unsigned int) cputime64_sub(cur_idle_time, + info->prev_cpu_idle); + info->prev_cpu_idle = cur_idle_time; + + if (unlikely(!wall_time || wall_time < idle_time)) + continue; + + /* load is the percentage of time not spent in idle */ + load = 100 * (wall_time - idle_time) / wall_time; + info->load[info->idx++] = load; + if (info->idx >= LOAD_MONITOR) + info->idx = 0; + + hp_printk("cpu %d load %u ", i, load); + + total_load += load; + } + + return total_load; +} + +static unsigned long determine_cpu_load_trend(void) +{ + int i, k; + unsigned long total_load = 0; + + /* Get cpu load of each cpu */ + for_each_online_cpu(i) { + unsigned int load = 0; + struct hotplug_cpu_info *info; + + info = &per_cpu(hotplug_info, i); + + for (k = 0; k < LOAD_MONITOR; k++) + load += info->load[k]; + + load /= LOAD_MONITOR; + + hp_printk("cpu %d load trend %u\n", i, load); + + total_load += load; + } + + return total_load; +} + +static unsigned long determine_cpu_balance_trend(void) +{ + int i, k; + unsigned long total_load = 0; + unsigned long min_load = (unsigned long) (-1); + + /* Get cpu load of each cpu */ + for_each_online_cpu(i) { + unsigned int load = 0; + struct hotplug_cpu_info *info; + info = &per_cpu(hotplug_info, i); + + for (k = 0; k < LOAD_MONITOR; k++) + load += info->load[k]; + + load /= LOAD_MONITOR; + + if (min_load > load) + min_load = load; + total_load += load; + } + + if (min_load > min_trend) + total_load = (100 * total_load) / min_load; + else + total_load = 50 << num_online_cpus(); + + return total_load; +} + +static void init_cpu_load_trend(void) +{ + int i; + + for_each_possible_cpu(i) { + struct hotplug_cpu_info *info; + int j; + + info = &per_cpu(hotplug_info, i); + + info->prev_cpu_idle = get_cpu_idle_time_us(i, + &(info->prev_cpu_wall)); + info->prev_cpu_io = get_cpu_iowait_time_us(i, + &(info->prev_cpu_wall)); + + for (j = 0; j < LOAD_MONITOR; j++) { + info->load[j] = 100; + } + info->idx = 0; + } +} + +static u32 get_num_interrupts_per_s(void) +{ + int cpu; + int i; + u64 num_irqs = 0; + ktime_t now; + static ktime_t last; + unsigned int delta; + u32 irqs = 0; + + now = ktime_get(); + + for_each_possible_cpu(cpu) { + for (i = 0; i < NR_IRQS; i++) + num_irqs += kstat_irqs_cpu(i, cpu); + } + pr_debug("%s: total num irqs: %lld, previous %lld\n", + __func__, num_irqs, old_num_irqs); + + if (old_num_irqs > 0) { + delta = (u32)ktime_to_ms(ktime_sub(now, last)) / 1000; + irqs = ((u32)(num_irqs - old_num_irqs)) / delta; + } + + old_num_irqs = num_irqs; + last = now; + + pr_debug("delta irqs per sec:%d\n", irqs); + + return irqs; +} + +static int set_cpufreq(int cpu, int min_freq, int max_freq) +{ + int ret; + struct cpufreq_policy policy; + + pr_debug("set cpu freq: min %d max: %d\n", min_freq, max_freq); + + ret = cpufreq_get_policy(&policy, cpu); + if (ret < 0) { + pr_err("usecase-gov: failed to read policy\n"); + return ret; + } + + if (policy.min > max_freq) { + ret = cpufreq_update_freq(cpu, min_freq, policy.max); + if (ret) + pr_err("usecase-gov: update min cpufreq failed (1)\n"); + } + if (policy.max < min_freq) { + ret = cpufreq_update_freq(cpu, policy.min, max_freq); + if (ret) + pr_err("usecase-gov: update max cpufreq failed (2)\n"); + } + + ret = cpufreq_update_freq(cpu, min_freq, max_freq); + if (ret) + pr_err("usecase-gov: update min-max cpufreq failed\n"); + + return ret; +} + +static void set_cpu_config(enum ux500_uc new_uc) +{ + bool update = false; + int cpu; + int max_freq, min_freq; + + if (new_uc != current_uc) + update = true; + else if ((user_config_updated) && (new_uc == UX500_UC_USER)) + update = true; + + pr_debug("%s: new_usecase=%d, current_usecase=%d, update=%d\n", + __func__, new_uc, current_uc, update); + + if (!update) + goto exit; + + /* Cpu hotplug */ + if (!(usecase_conf[new_uc].second_cpu_online) && + (num_online_cpus() > 1)) + cpu_down(1); + else if ((usecase_conf[new_uc].second_cpu_online) && + (num_online_cpus() < 2)) + cpu_up(1); + + if(usecase_conf[new_uc].max_arm_opp) + max_freq = dbx500_cpufreq_percent2freq(usecase_conf[new_uc].max_arm_opp); + else + /* Maximum OPP is 125% */ + max_freq = dbx500_cpufreq_percent2freq(125); + + min_freq = dbx500_cpufreq_percent2freq(usecase_conf[new_uc].min_arm_opp); + + for_each_online_cpu(cpu) { + set_cpufreq(cpu, + min_freq, + max_freq); + } + + /* Kinda doing the job twice, but this is needed for reference keeping */ + prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP, + "usecase", usecase_conf[new_uc].min_arm_opp); + + /* Cpu idle */ + cpuidle_set_multiplier(usecase_conf[new_uc].cpuidle_multiplier); + + /* L2 prefetch */ + if (usecase_conf[new_uc].l2_prefetch_en) + outer_prefetch_enable(); + else + outer_prefetch_disable(); + + /* Force cpuidle state */ + cpuidle_force_state(usecase_conf[new_uc].forced_state); + + /* QOS override */ + prcmu_qos_voice_call_override(usecase_conf[new_uc].vc_override); + + current_uc = new_uc; + +exit: + /* Its ok to clear even if new_uc != UX500_UC_USER */ + user_config_updated = false; +} + +void usecase_update_governor_state(void) +{ + bool cancel_work = false; + + /* + * usecase_mutex will have to be unlocked to ensure safe exit of + * delayed_usecase_work(). Protect this function with its own mutex + * from being executed by multiple threads at that point. + */ + mutex_lock(&state_mutex); + mutex_lock(&usecase_mutex); + + if (uc_master_enable && (usecase_conf[UX500_UC_AUTO].enable || + usecase_conf[UX500_UC_USER].enable)) { + /* + * Usecases are enabled. If we are in early suspend put + * governor to work. + */ + if (is_early_suspend && !is_work_scheduled) { + schedule_delayed_work_on(0, &work_usecase, + msecs_to_jiffies(CPULOAD_MEAS_DELAY)); + is_work_scheduled = true; + } else if (!is_early_suspend && is_work_scheduled) { + /* Exiting from early suspend. */ + cancel_work = true; + } + + } else if (is_work_scheduled) { + /* No usecase enabled or governor is not enabled. */ + cancel_work = true; + } + + if (cancel_work) { + /* + * usecase_mutex is used by delayed_usecase_work() so it must + * be unlocked before we call to cacnel the work. + */ + mutex_unlock(&usecase_mutex); + cancel_delayed_work_sync(&work_usecase); + mutex_lock(&usecase_mutex); + + is_work_scheduled = false; + + /* Set the default settings before exiting. */ + set_cpu_config(UX500_UC_NORMAL); + } + + mutex_unlock(&usecase_mutex); + mutex_unlock(&state_mutex); +} + +/* + * Start load measurment every 6 s in order detrmine if can unplug one CPU. + * In order to not corrupt measurment, the first load average is not done + * here call in early suspend. + */ +static void usecase_earlysuspend_callback(struct early_suspend *h) +{ + init_cpu_load_trend(); + + is_early_suspend = true; + + usecase_update_governor_state(); +} + +/* Stop measurement, call LCD early resume */ +static void usecase_lateresume_callback(struct early_suspend *h) +{ + is_early_suspend = false; + + usecase_update_governor_state(); +} + +static void delayed_usecase_work(struct work_struct *work) +{ + unsigned long avg, load, trend, balance; + bool inc_perf = false; + bool dec_perf = false; + u32 irqs_per_s; + + /* determine loadavg */ + avg = determine_loadavg(); + hp_printk("loadavg = %lu lower th %lu upper th %lu\n", + avg, lower_threshold, upper_threshold); + + /* determine instant load */ + load = determine_cpu_load(); + hp_printk("cpu instant load = %lu max %lu\n", load, max_instant); + + /* determine load trend */ + trend = determine_cpu_load_trend(); + hp_printk("cpu load trend = %lu min %lu unbal %lu\n", + trend, min_trend, trend_unbalance); + + /* determine load balancing */ + balance = determine_cpu_balance_trend(); + hp_printk("load balancing trend = %lu min %lu\n", + balance, max_unbalance); + + irqs_per_s = get_num_interrupts_per_s(); + + /* Dont let configuration change in the middle of our calculations. */ + mutex_lock(&usecase_mutex); + + /* detect "instant" load increase */ + if (load > max_instant || irqs_per_s > exit_irq_per_s) { + inc_perf = true; + } else if (!usecase_conf[UX500_UC_USER].enable && + usecase_conf[UX500_UC_AUTO].enable) { + /* detect high loadavg use case */ + if (avg > upper_threshold) + inc_perf = true; + /* detect idle use case */ + else if (trend < min_trend) + dec_perf = true; + /* detect unbalanced low cpu load use case */ + else if ((balance > max_unbalance) && (trend < trend_unbalance)) + dec_perf = true; + /* detect low loadavg use case */ + else if (avg < lower_threshold) + dec_perf = true; + /* All user use cases disabled, current load not triggering + * any change. + */ + else if (user_config_updated) + dec_perf = true; + } else { + dec_perf = true; + } + + /* + * set_cpu_config() will not update the config unless it has been + * changed. + */ + if (dec_perf) { + if (usecase_conf[UX500_UC_USER].enable) + set_cpu_config(UX500_UC_USER); + else if (usecase_conf[UX500_UC_AUTO].enable) + set_cpu_config(UX500_UC_AUTO); + } else if (inc_perf) { + set_cpu_config(UX500_UC_NORMAL); + } + + mutex_unlock(&usecase_mutex); + + /* reprogramm scheduled work */ + schedule_delayed_work_on(0, &work_usecase, + msecs_to_jiffies(CPULOAD_MEAS_DELAY)); + +} + +static struct dentry *usecase_dir; + +#ifdef CONFIG_DEBUG_FS +#define define_set(_name) \ +static ssize_t set_##_name(struct file *file, \ + const char __user *user_buf, \ + size_t count, loff_t *ppos) \ +{ \ + int err; \ + long unsigned i; \ + \ + err = kstrtoul_from_user(user_buf, count, 0, &i); \ + \ + if (err) \ + return err; \ + \ + _name = i; \ + hp_printk("New value : %lu\n", _name); \ + \ + return count; \ +} + +define_set(upper_threshold); +define_set(lower_threshold); +define_set(max_unbalance); +define_set(trend_unbalance); +define_set(min_trend); +define_set(max_instant); +define_set(debug); + +#define define_print(_name) \ +static ssize_t print_##_name(struct seq_file *s, void *p) \ +{ \ + return seq_printf(s, "%lu\n", _name); \ +} + +define_print(upper_threshold); +define_print(lower_threshold); +define_print(max_unbalance); +define_print(trend_unbalance); +define_print(min_trend); +define_print(max_instant); +define_print(debug); + +#define define_open(_name) \ +static ssize_t open_##_name(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, print_##_name, inode->i_private); \ +} + +define_open(upper_threshold); +define_open(lower_threshold); +define_open(max_unbalance); +define_open(trend_unbalance); +define_open(min_trend); +define_open(max_instant); +define_open(debug); + +#define define_dbg_file(_name) \ +static const struct file_operations fops_##_name = { \ + .open = open_##_name, \ + .write = set_##_name, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + .owner = THIS_MODULE, \ +}; \ +static struct dentry *file_##_name; + +define_dbg_file(upper_threshold); +define_dbg_file(lower_threshold); +define_dbg_file(max_unbalance); +define_dbg_file(trend_unbalance); +define_dbg_file(min_trend); +define_dbg_file(max_instant); +define_dbg_file(debug); + +struct dbg_file { + struct dentry **file; + const struct file_operations *fops; + const char *name; +}; + +#define define_dbg_entry(_name) \ +{ \ + .file = &file_##_name, \ + .fops = &fops_##_name, \ + .name = #_name \ +} + +static struct dbg_file debug_entry[] = { + define_dbg_entry(upper_threshold), + define_dbg_entry(lower_threshold), + define_dbg_entry(max_unbalance), + define_dbg_entry(trend_unbalance), + define_dbg_entry(min_trend), + define_dbg_entry(max_instant), + define_dbg_entry(debug), +}; + +static int setup_debugfs(void) +{ + int i; + usecase_dir = debugfs_create_dir("usecase", NULL); + + if (IS_ERR_OR_NULL(usecase_dir)) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(debug_entry); i++) { + if (IS_ERR_OR_NULL(debugfs_create_file(debug_entry[i].name, + S_IWUGO | S_IRUGO, + usecase_dir, + NULL, + debug_entry[i].fops))) + goto fail; + } + + if (IS_ERR_OR_NULL(debugfs_create_u32("exit_irq_per_s", + S_IWUGO | S_IRUGO, usecase_dir, + &exit_irq_per_s))) + goto fail; + return 0; +fail: + debugfs_remove_recursive(usecase_dir); + return -EINVAL; +} +#else +static int setup_debugfs(void) +{ + return 0; +} +#endif + +static void usecase_update_user_config(void) +{ + int i; + bool config_enable = false; + struct usecase_config *user_conf = &usecase_conf[UX500_UC_USER]; + + mutex_lock(&usecase_mutex); + + user_conf->min_arm_opp = 25; + user_conf->max_arm_opp = 0; + user_conf->cpuidle_multiplier = 0; + user_conf->second_cpu_online = false; + user_conf->l2_prefetch_en = false; + user_conf->forced_state = cpuidle_deepest_state; + user_conf->vc_override = true; /* A single false will clear it. */ + + /* Dont include Auto and Normal modes in this */ + for (i = (UX500_UC_AUTO + 1); i < UX500_UC_USER; i++) { + if (!usecase_conf[i].enable) + continue; + + config_enable = true; + + /* It's the highest arm opp requirement that should be used */ + if (usecase_conf[i].min_arm_opp > user_conf->min_arm_opp) + user_conf->min_arm_opp = usecase_conf[i].min_arm_opp; + + if (usecase_conf[i].max_arm_opp > user_conf->max_arm_opp) + user_conf->max_arm_opp = usecase_conf[i].max_arm_opp; + + if (usecase_conf[i].cpuidle_multiplier > + user_conf->cpuidle_multiplier) + user_conf->cpuidle_multiplier = + usecase_conf[i].cpuidle_multiplier; + + user_conf->second_cpu_online |= + usecase_conf[i].second_cpu_online; + + user_conf->l2_prefetch_en |= + usecase_conf[i].l2_prefetch_en; + + /* Take the shallowest state. */ + if (usecase_conf[i].forced_state < user_conf->forced_state) + user_conf->forced_state = usecase_conf[i].forced_state; + + /* Only override QOS if all enabled configurations are + * requesting it. + */ + if (!usecase_conf[i].vc_override) + user_conf->vc_override = false; + } + + user_conf->enable = config_enable; + user_config_updated = true; + + mutex_unlock(&usecase_mutex); +} + +struct usecase_devclass_attr { + struct sysdev_class_attribute class_attr; + u32 index; +}; + +/* One for each usecase except "user" + current + enable */ +#define UX500_NUM_SYSFS_NODES (UX500_UC_USER + 2) +#define UX500_CURRENT_NODE_INDEX (UX500_NUM_SYSFS_NODES - 1) +#define UX500_ENABLE_NODE_INDEX (UX500_NUM_SYSFS_NODES - 2) + +static struct usecase_devclass_attr usecase_dc_attr[UX500_NUM_SYSFS_NODES]; + +static struct attribute *dbs_attributes[UX500_NUM_SYSFS_NODES + 1] = {NULL}; + +static struct attribute_group dbs_attr_group = { + .attrs = dbs_attributes, + .name = "usecase", +}; + +static ssize_t show_current(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) +{ + enum ux500_uc display_uc = (current_uc == UX500_UC_MAX) ? + UX500_UC_NORMAL : current_uc; + + return sprintf(buf, "min_arm_opp: %d\n" + "max_arm_opp: %d\n" + "cpuidle_multiplier: %ld\n" + "second_cpu_online: %s\n" + "l2_prefetch_en: %s\n" + "forced_state: %d\n" + "vc_override: %s\n", + usecase_conf[display_uc].min_arm_opp, + usecase_conf[display_uc].max_arm_opp, + usecase_conf[display_uc].cpuidle_multiplier, + usecase_conf[display_uc].second_cpu_online ? "true" : "false", + usecase_conf[display_uc].l2_prefetch_en ? "true" : "false", + usecase_conf[display_uc].forced_state, + usecase_conf[display_uc].vc_override ? "true" : "false"); +} + +static ssize_t show_enable(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", uc_master_enable); +} + +static ssize_t store_enable(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + ret = sscanf(buf, "%u", &input); + if (ret != 1) + return -EINVAL; + + uc_master_enable = (bool) input; + + usecase_update_governor_state(); + + return count; +} + +static ssize_t show_dc_attr(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) +{ + struct usecase_devclass_attr *uattr = + container_of(attr, struct usecase_devclass_attr, class_attr); + + return sprintf(buf, "%u\n", + usecase_conf[uattr->index].enable); +} + +static ssize_t store_dc_attr(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + struct usecase_devclass_attr *uattr = + container_of(attr, struct usecase_devclass_attr, class_attr); + + ret = sscanf(buf, "%u", &input); + + /* Normal mode cant be changed. */ + if ((ret != 1) || (uattr->index == 0)) + return -EINVAL; + + usecase_conf[uattr->index].enable = (bool)input; + + if (uattr->index == UX500_UC_VC) + prcmu_vc(usecase_conf[UX500_UC_VC].enable); + + usecase_update_user_config(); + + usecase_update_governor_state(); + + return count; +} + +static int usecase_sysfs_init(void) +{ + int err; + int i; + + /* Last two nodes are not based on usecase configurations */ + for (i = 0; i < (UX500_NUM_SYSFS_NODES - 2); i++) { + usecase_dc_attr[i].class_attr.attr.name = usecase_conf[i].name; + usecase_dc_attr[i].class_attr.attr.mode = 0644; + usecase_dc_attr[i].class_attr.show = show_dc_attr; + usecase_dc_attr[i].class_attr.store = store_dc_attr; + usecase_dc_attr[i].index = i; + + dbs_attributes[i] = &(usecase_dc_attr[i].class_attr.attr); + } + + /* sysfs current */ + usecase_dc_attr[UX500_CURRENT_NODE_INDEX].class_attr.attr.name = + "current"; + usecase_dc_attr[UX500_CURRENT_NODE_INDEX].class_attr.attr.mode = + 0644; + usecase_dc_attr[UX500_CURRENT_NODE_INDEX].class_attr.show = + show_current; + usecase_dc_attr[UX500_CURRENT_NODE_INDEX].class_attr.store = + NULL; + usecase_dc_attr[UX500_CURRENT_NODE_INDEX].index = + 0; + dbs_attributes[UX500_CURRENT_NODE_INDEX] = + &(usecase_dc_attr[UX500_CURRENT_NODE_INDEX].class_attr.attr); + + /* sysfs enable */ + usecase_dc_attr[UX500_ENABLE_NODE_INDEX].class_attr.attr.name = + "enable"; + usecase_dc_attr[UX500_ENABLE_NODE_INDEX].class_attr.attr.mode = + 0644; + usecase_dc_attr[UX500_ENABLE_NODE_INDEX].class_attr.show = + show_enable; + usecase_dc_attr[UX500_ENABLE_NODE_INDEX].class_attr.store = + store_enable; + usecase_dc_attr[UX500_ENABLE_NODE_INDEX].index = + 0; + dbs_attributes[UX500_ENABLE_NODE_INDEX] = + &(usecase_dc_attr[UX500_ENABLE_NODE_INDEX].class_attr.attr); + + err = sysfs_create_group(&(cpu_sysdev_class.kset.kobj), + &dbs_attr_group); + if (err) + pr_err("usecase-gov: sysfs_create_group" + " failed with error = %d\n", err); + + return err; +} + +static void usecase_cpuidle_init(void) +{ + int max_states; + int i; + struct cstate *state = ux500_ci_get_cstates(&max_states); + + for (i = 0; i < max_states; i++) + if ((state[i].APE == APE_OFF) && (state[i].ARM == ARM_RET)) + break; + + usecase_conf[UX500_UC_LPA].forced_state = i; + + cpuidle_deepest_state = max_states - 1; +} + +/* initialize devices */ +static int __init init_usecase_devices(void) +{ + int err; + + pr_info("Use-case governor initialized\n"); + + /* add early_suspend callback */ + usecase_early_suspend.level = 200; + usecase_early_suspend.suspend = usecase_earlysuspend_callback; + usecase_early_suspend.resume = usecase_lateresume_callback; + register_early_suspend(&usecase_early_suspend); + + /* register delayed queuework */ + INIT_DELAYED_WORK_DEFERRABLE(&work_usecase, + delayed_usecase_work); + + init_cpu_load_trend(); + + err = setup_debugfs(); + if (err) + goto error; + err = usecase_sysfs_init(); + if (err) + goto error2; + + usecase_cpuidle_init(); + + prcmu_qos_add_requirement(PRCMU_QOS_ARM_OPP, "usecase", 25); + + return 0; +error2: + debugfs_remove_recursive(usecase_dir); +error: + unregister_early_suspend(&usecase_early_suspend); + return err; +} + +device_initcall(init_usecase_devices); diff --git a/arch/arm/mach-ux500/prcc.h b/arch/arm/mach-ux500/prcc.h new file mode 100644 index 00000000000..4224e478348 --- /dev/null +++ b/arch/arm/mach-ux500/prcc.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2009-2011 ST-Ericsson SA + * + * 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 __MACH_UX500_PRCC_H__ + +#define PRCC_PCKEN 0x000 +#define PRCC_PCKDIS 0x004 +#define PRCC_KCKEN 0x008 +#define PRCC_KCKDIS 0x00C +#define PRCC_PCKSR 0x010 +#define PRCC_KCKSR 0x014 +#define PRCC_K_SOFTRST_SET 0x018 +#define PRCC_K_SOFTRST_CLR 0x01C +#define PRCC_K_RST_STATUS 0x020 + +#endif diff --git a/arch/arm/mach-ux500/prcmu-debug.c b/arch/arm/mach-ux500/prcmu-debug.c new file mode 100644 index 00000000000..6842e4b68fe --- /dev/null +++ b/arch/arm/mach-ux500/prcmu-debug.c @@ -0,0 +1,1041 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * + * Author: Martin Persson for ST-Ericsson + * Etienne Carriere <etienne.carriere@stericsson.com> for ST-Ericsson + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include <mach/hardware.h> + +#define MAX_STATES 5 +#define MAX_NAMELEN 16 +#define U8500_PRCMU_TCDM_SIZE 4096 + +struct state_history { + ktime_t start; + u32 state; + u32 counter[MAX_STATES]; + u8 opps[MAX_STATES]; + int max_states; + int req; + bool reqs[MAX_STATES]; + ktime_t time[MAX_STATES]; + int state_names[MAX_STATES]; + char prefix[MAX_NAMELEN]; + spinlock_t lock; +}; + +static struct state_history ape_sh = { + .prefix = "APE", + .req = PRCMU_QOS_APE_OPP, + .opps = {APE_50_OPP, APE_100_OPP}, + .state_names = {50, 100}, + .max_states = 2, +}; + +static struct state_history ddr_sh = { + .prefix = "DDR", + .req = PRCMU_QOS_DDR_OPP, + .opps = {DDR_25_OPP, DDR_50_OPP, DDR_100_OPP}, + .state_names = {25, 50, 100}, + .max_states = 3, +}; + +static struct state_history arm_sh = { + .prefix = "ARM", + .req = PRCMU_QOS_ARM_OPP, + .opps = {ARM_EXTCLK, ARM_50_OPP, ARM_100_OPP, ARM_MAX_OPP}, + .state_names = {25, 50, 100, 125}, + .max_states = 4, +}; + +static const u16 u8500_prcmu_dump_regs[] = { + /*ARMCLKFIX_MGT*/ 0x0, /*ACLK_MGT*/ 0x4, + /*SVAMMDSPCLK_MGT*/ 0x8, /*SIAMMDSPCLK_MGT*/ 0xc, + /*SGACLK_MGT*/ 0x14, /*UARTCLK_MGT*/ 0x18, + /*MSP02CLK_MGT*/ 0x1c, /*I2CCLK_MGT*/ 0x20, + /*SDMMCCLK_MGT*/ 0x24, /*SLIMCLK_MGT*/ 0x28, + /*PER1CLK_MGT*/ 0x2c, /*PER2CLK_MGT*/ 0x30, + /*PER3CLK_MGT*/ 0x34, /*PER5CLK_MGT*/ 0x38, + /*PER6CLK_MGT*/ 0x3c, /*PER7CLK_MGT*/ 0x40, + /*LCDCLK_MGT*/ 0x44, /*SPARE1CLK_MGT*/ 0x48, + /*BMLCLK_MGT*/ 0x4c, /*HSITXCLK_MGT*/ 0x50, + /*HSIRXCLK_MGT*/ 0x54, /*HDMICLK_MGT*/ 0x58, + /*APEATCLK_MGT*/ 0x5c, /*APETRACECLK_MGT*/ 0x60, + /*MCDECLK_MGT*/ 0x64, /*IPI2CCLK_MGT*/ 0x68, + /*DSIALTCLK_MGT*/ 0x6c, /*SPARE2CLK_MGT*/ 0x70, + /*DMACLK_MGT*/ 0x74, /*B2R2CLK_MGT*/ 0x78, + /*TVCLK_MGT*/ 0x7c, /*PLLSOC0_FREQ*/ 0x80, + /*PLLSOC1_FREQ*/ 0x84, /*PLLARM_FREQ*/ 0x88, + /*PLLDDR_FREQ*/ 0x8c, /*PLLSOC0_ENABLE*/ 0x90, + /*PLLSOC1_ENABLE*/ 0x94, /*PLLARM_ENABLE*/ 0x98, + /*PLLDDR_ENABLE*/ 0x9c, /*PLLSOC0_LOCKP*/ 0xa0, + /*PLLSOC1_LOCKP*/ 0xa4, /*PLLARM_LOCKP*/ 0xa8, + /*PLLDDR_LOCKP*/ 0xac, /*XP70CLK_MGT*/ 0xb0, + /*TIMER_0_REF*/ 0xb4, /*TIMER_0_DOWNCOUNT*/ 0xb8, + /*TIMER_0_MODE*/ 0xbc, /*TIMER_1_REF*/ 0xc0, + /*TIMER_1_DOWNCOUNT*/ 0xc4, /*TIMER_1_MODE*/ 0xc8, + /*TIMER_2_REF*/ 0xcc, /*TIMER_2_DOWNCOUNT*/ 0xd0, + /*TIMER_2_MODE*/ 0xd4, /*CLK009_MGT*/ 0xe4, + /*MODECLK*/ 0xe8, /*4500_CLK_REQ*/ 0xf8, + /*MBOX_CPU_VAL*/ 0xfc, /*PLL32K_ENABLE*/ 0x10c, + /*PLL32K_LOCKP*/ 0x110, /*ARM_CHGCLKREQ*/ 0x114, + /*ARM_PLLDIVPS*/ 0x118, /*ARMITMSK31TO0*/ 0x11c, + /*ARMITMSK63TO32*/ 0x120, /*ARMITMSK95TO64*/ 0x124, + /*ARMITMSK127TO96*/ 0x128, /*ARMSTANDBY_STATUS*/ 0x130, + /*CGATING_BYPASS*/ 0x134, /*GPIOCR*/ 0x138, + /*LEMI*/ 0x13c, /*COMPCR*/ 0x140, + /*COMPSTA*/ 0x144, /*ITSTATUS0*/ 0x148, + /*ITSTATUS1*/ 0x150, /*ITSTATUS2*/ 0x158, + /*ITSTATUS3*/ 0x160, /*ITSTATUS4*/ 0x168, + /*LINE_VALUE*/ 0x170, /*HOLD_EVT*/ 0x174, + /*EDGE_SENS_L*/ 0x178, /*EDGE_SENS_H*/ 0x17c, + /*DEBUG_CTRL_VAL*/ 0x190, /*DEBUG_NOPWRDOWN_VAL*/ 0x194, + /*DEBUG_CTRL_ACK*/ 0x198, /*A9PL_FORCE_CLKEN*/ 0x19c, + /*TPIU_FLUSHIN_REQ*/ 0x1a0, /*TPIU_FLUSHIN_ACK*/ 0x1a4, + /*STP_FLUSHIN_REQ*/ 0x1a8, /*STP_FLUSHIN_ACK*/ 0x1ac, + /*HWI2C_DIV*/ 0x1b0, /*HWI2C_CMD*/ 0x1b8, + /*HWI2C_DATA123*/ 0x1bc, /*HWI2C_SR*/ 0x1c0, + /*REMAPCR*/ 0x1c4, /*TCR*/ 0x1c8, + /*CLKOCR*/ 0x1cc, /*ITSTATUS_DBG*/ 0x1d0, + /*LINE_VALUE_DBG*/ 0x1d8, /*DBG_HOLD*/ 0x1dc, + /*EDGE_SENS_DBG*/ 0x1e0, /*APE_RESETN_VAL*/ 0x1ec, + /*A9_RESETN_SET*/ 0x1f0, /*A9_RESETN_VAL*/ 0x1f8, + /*MOD_RESETN_VAL*/ 0x204, /*GPIO_RESETN_VAL*/ 0x210, + /*4500_RESETN_VAL*/ 0x21c, /*SWD_RST_TEMPO*/ 0x238, + /*RST_4500_TEMPO*/ 0x23c, /*SVAMMDSP_IT*/ 0x240, + /*SIAMMDSP_IT*/ 0x248, /*POWER_STATE_VAL*/ 0x25c, + /*ARMITVALUE31TO0*/ 0x260, /*ARMITVALUE63TO32*/ 0x264, + /*ARMITVALUE95TO64*/ 0x268, /*ARMITVALUE127TO96*/ 0x26c, + /*REDUN_LOAD*/ 0x270, /*REDUN_STATUS*/ 0x274, + /*UNIPROCLK_MGT*/ 0x278, /*UICCCLK_MGT*/ 0x27c, + /*SSPCLK_MGT*/ 0x280, /*RNGCLK_MGT*/ 0x284, + /*MSP1CLK_MGT*/ 0x288, /*DAP_RESETN_SET*/ 0x2a0, + /*DAP_RESETN_VAL*/ 0x2a8, /*SRAM_DEDCSTOV*/ 0x300, + /*SRAM_LS_SLEEP*/ 0x304, /*SRAM_A9*/ 0x308, + /*ARM_LS_CLAMP*/ 0x30c, /*IOCR*/ 0x310, + /*MODEM_SYSCLKOK*/ 0x314, /*SYSCLKOK_DELAY*/ 0x318, + /*SYSCLKSTATUS*/ 0x31c, /*DSI_SW_RESET*/ 0x324, + /*A9_MASK_REQ*/ 0x328, /*A9_MASK_ACK*/ 0x32c, + /*HOSTACCESS_REQ*/ 0x334, /*TIMER_3_REF*/ 0x338, + /*TIMER_3_DOWNCOUNT*/ 0x33c, /*TIMER_3_MODE*/ 0x340, + /*PMB_SENS_CTRL*/ 0x344, /*PMB_REF_COUNTER*/ 0x348, + /*PMB_SENSOR_STATUS*/ 0x34c, /*APE_EPOD_CFG*/ 0x404, + /*DDR_EPOD_CFG*/ 0x408, /*EPOD_C_VAL*/ 0x418, + /*EPOD_VOK*/ 0x41c, /*MMIP_LS_CLAMP_VAL*/ 0x428, + /*VSAFE_LS_CLAMP_VAL*/ 0x434, /*DDRSUBSYS_APE_MINBW*/ 0x438, + /*DDRSUBSYS_STATUS*/ 0x43c, /*DDRSUBSYS_CONTROL*/ 0x440, + /*DDRSUBSYS_HIGH_LEAK_COND*/ 0x444, /*DDRSUBSYS_CONFIG*/ 0x448, + /*TIMER_4_REF*/ 0x450, /*TIMER_4_DOWNCOUNT*/ 0x454, + /*TIMER_4_MODE*/ 0x458, /*TIMER_5_REF*/ 0x45c, + /*TIMER_5_DOWNCOUNT*/ 0x460, /*TIMER_5_MODE*/ 0x464, + /*APE_MEM_REQ*/ 0x470, /*DBG_FRCS_APE_MEM_REQ*/ 0x474, + /*APE_MEM_WFX_EN*/ 0x478, /*APE_MEM_LATENCY*/ 0x47c, + /*APE_MEM_ACK*/ 0x480, /*ITSTATUS5*/ 0x484, + /*ARM_IT1_VAL*/ 0x494, /*MOD_PWR_OK*/ 0x498, + /*MOD_AUXCLKOK*/ 0x49c, /*MOD_AWAKE_STATUS*/ 0x4a0, + /*MOD_SWRESET_IRQ_ACK*/ 0x4a4, /*MOD_SWRESET_ACK*/ 0x4a8, + /*DBG_PWRCTL*/ 0x4ac, /*HWOBS_H*/ 0x4b0, + /*HWOBS_L*/ 0x4b4, /*PLLDSI_FREQ*/ 0x500, + /*PLLDSI_ENABLE*/ 0x504, /*PLLDSI_LOCKP*/ 0x508, + /*RNG_ENABLE*/ 0x50c, /*YYCLKEN0_MGT_SET*/ 0x510, + /*YYCLKEN0_MGT_VAL*/ 0x520, /*YYCLKEN1_MGT_VAL*/ 0x524, + /*XP70CLK_MGT2*/ 0x528, /*DSITVCLK_DIV*/ 0x52c, + /*DSI_PLLOUT_SEL*/ 0x530, /*DSI_GLITCHFREE_EN*/ 0x534, + /*CLKACTIV*/ 0x538, /*SIA_MMDSP_MEM_MGT*/ 0x53c, + /*SVA_MMDSP_MEM_MGT*/ 0x540, /*SXAMMDSP_FORCE_CLKEN*/ 0x544, + /*UICC_NANDTREE*/ 0x570, /*GPIOCR2*/ 0x574, + /*MDM_ACWAKE*/ 0x578, /*MOD_MEM_REQ*/ 0x5a4, + /*MOD_MEM_ACK*/ 0x5a8, /*ARM_PLLDIVPS_REQ*/ 0x5b0, + /*ARM_PLLDIVPS_ACK*/ 0x5b4, /*SRPTIMER_VAL*/ 0x5d0, +}; + +/* Offsets from secure base which is U8500_PRCMU_BASE + SZ_4K */ +static const u16 u8500_prcmu_dump_secure_regs[] = { + /*SECNONSEWM*/ 0x00, /*ESRAM0_INITN*/ 0x04, + /*ARMITMSKSEC_31TO0*/ 0x08, /*ARMITMSKSEC_63TO32*/ 0x0C, + /*ARMITMSKSEC_95TO64*/ 0x10, /*ARMITMSKSEC_127TO96*/ 0x14, + /*ARMIT_MASKXP70_IT*/ 0x18, /*ESRAM0_EPOD_CFG*/ 0x1C, + /*ESRAM0_EPOD_C_VAL*/ 0x20, /*ESRAM0_EPOD_VOK*/ 0x2C, + /*ESRAM0_LS_SLEEP*/ 0x30, /*SECURE_ONGOING*/ 0x34, + /*I2C_SECURE*/ 0x38, /*RESET_STATUS*/ 0x3C, + /*PERIPH4_RESETN_VAL*/ 0x48, /*SPAREOUT_SEC*/ 0x4C, + /*PIPELINEDCR*/ 0xD8, +}; + +static int ape_voltage_count; + +static void log_set(struct state_history *sh, u8 opp) +{ + ktime_t now; + ktime_t dtime; + unsigned long flags; + int state; + + now = ktime_get(); + spin_lock_irqsave(&sh->lock, flags); + + for (state = 0 ; sh->opps[state] != opp; state++) + ; + BUG_ON(state >= sh->max_states); + + dtime = ktime_sub(now, sh->start); + sh->time[sh->state] = ktime_add(sh->time[sh->state], dtime); + sh->start = now; + sh->counter[sh->state]++; + sh->state = state; + + spin_unlock_irqrestore(&sh->lock, flags); +} + +void prcmu_debug_ape_opp_log(u8 opp) +{ + if (opp == APE_50_PARTLY_25_OPP) + opp = APE_50_OPP; + + log_set(&ape_sh, opp); +} + +void prcmu_debug_ddr_opp_log(u8 opp) +{ + log_set(&ddr_sh, opp); +} + +void prcmu_debug_arm_opp_log(u8 opp) +{ + log_set(&arm_sh, opp); +} + +static void log_reset(struct state_history *sh) +{ + unsigned long flags; + int i; + + pr_info("reset\n"); + + spin_lock_irqsave(&sh->lock, flags); + for (i = 0; i < sh->max_states; i++) { + sh->counter[i] = 0; + sh->time[i] = ktime_set(0, 0); + } + + sh->start = ktime_get(); + spin_unlock_irqrestore(&sh->lock, flags); + +} + +static ssize_t ape_stats_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + log_reset(&ape_sh); + return count; +} + +static ssize_t ddr_stats_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + log_reset(&ddr_sh); + return count; +} + +static ssize_t arm_stats_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + log_reset(&arm_sh); + return count; +} + +static int log_print(struct seq_file *s, struct state_history *sh) +{ + int i; + unsigned long flags; + ktime_t total; + ktime_t dtime; + s64 t_ms; + s64 perc; + s64 total_ms; + + spin_lock_irqsave(&sh->lock, flags); + + dtime = ktime_sub(ktime_get(), sh->start); + + total = dtime; + + for (i = 0; i < sh->max_states; i++) + total = ktime_add(total, sh->time[i]); + total_ms = ktime_to_ms(total); + + for (i = 0; i < sh->max_states; i++) { + ktime_t t = sh->time[i]; + if (sh->state == i) + t = ktime_add(t, dtime); + + t_ms = ktime_to_ms(t); + perc = 100 * t_ms; + do_div(perc, total_ms); + + seq_printf(s, "%s OPP %d: # %u in %lld ms %d%%\n", + sh->prefix, sh->state_names[i], + sh->counter[i] + (int)(sh->state == i), + t_ms, (u32)perc); + + } + spin_unlock_irqrestore(&sh->lock, flags); + return 0; +} + +static int ape_stats_print(struct seq_file *s, void *p) +{ + log_print(s, &ape_sh); + return 0; +} + +static int ddr_stats_print(struct seq_file *s, void *p) +{ + log_print(s, &ddr_sh); + return 0; +} + +static int arm_stats_print(struct seq_file *s, void *p) +{ + log_print(s, &arm_sh); + return 0; +} + +static int opp_read(struct seq_file *s, void *p) +{ + int opp; + + struct state_history *sh = (struct state_history *)s->private; + + switch (sh->req) { + case PRCMU_QOS_DDR_OPP: + opp = prcmu_get_ddr_opp(); + seq_printf(s, "%s (%d)\n", + (opp == DDR_100_OPP) ? "100%" : + (opp == DDR_50_OPP) ? "50%" : + (opp == DDR_25_OPP) ? "25%" : + "unknown", opp); + break; + case PRCMU_QOS_APE_OPP: + opp = prcmu_get_ape_opp(); + seq_printf(s, "%s (%d)\n", + (opp == APE_100_OPP) ? "100%" : + (opp == APE_50_OPP) ? "50%" : + "unknown", opp); + break; + case PRCMU_QOS_ARM_OPP: + opp = prcmu_get_arm_opp(); + seq_printf(s, "%s (%d)\n", + (opp == ARM_MAX_OPP) ? "max" : + (opp == ARM_MAX_FREQ100OPP) ? "max-freq100" : + (opp == ARM_100_OPP) ? "100%" : + (opp == ARM_50_OPP) ? "50%" : + (opp == ARM_EXTCLK) ? "25% (extclk)" : + "unknown", opp); + break; + default: + break; + } + return 0; + +} + +static ssize_t opp_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + long unsigned i; + int err; + struct state_history *sh = (struct state_history *) + ((struct seq_file *)file->private_data)->private; + + err = kstrtoul_from_user(user_buf, count, 0, &i); + + if (err) + return err; + + prcmu_qos_force_opp(sh->req, i); + + pr_info("prcmu debug: forced OPP for %s to %d\n", sh->prefix, (int)i); + + return count; +} + +static int cpufreq_delay_read(struct seq_file *s, void *p) +{ + return seq_printf(s, "%lu\n", prcmu_qos_get_cpufreq_opp_delay()); +} + +static int ape_voltage_read(struct seq_file *s, void *p) +{ + return seq_printf(s, "This reference count only includes " + "requests via debugfs.\nCount: %d\n", + ape_voltage_count); +} + +static ssize_t ape_voltage_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + long unsigned i; + int err; + + err = kstrtoul_from_user(user_buf, count, 0, &i); + + if (err) + return err; + + switch (i) { + case 0: + if (ape_voltage_count == 0) + pr_info("prcmu debug: reference count is already 0\n"); + else { + err = prcmu_request_ape_opp_100_voltage(false); + if (err) + pr_err("prcmu debug: drop request failed\n"); + else + ape_voltage_count--; + } + break; + case 1: + err = prcmu_request_ape_opp_100_voltage(true); + if (err) + pr_err("prcmu debug: request failed\n"); + else + ape_voltage_count++; + break; + default: + pr_info("prcmu debug: value not equal to 0 or 1\n"); + } + return count; +} + +static ssize_t cpufreq_delay_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + int err; + long unsigned i; + + err = kstrtoul_from_user(user_buf, count, 0, &i); + + if (err) + return err; + + prcmu_qos_set_cpufreq_opp_delay(i); + + pr_info("prcmu debug: changed delay between cpufreq change and QoS " + "requirement to %lu.\n", i); + + return count; +} + +/* These are only for u8500 */ +#define PRCM_AVS_BASE 0x2FC +#define AVS_VBB_RET 0x0 +#define AVS_VBB_MAX_OPP 0x1 +#define AVS_VBB_100_OPP 0x2 +#define AVS_VBB_50_OPP 0x3 +#define AVS_VARM_MAX_OPP 0x4 +#define AVS_VARM_100_OPP 0x5 +#define AVS_VARM_50_OPP 0x6 +#define AVS_VARM_RET 0x7 +#define AVS_VAPE_100_OPP 0x8 +#define AVS_VAPE_50_OPP 0x9 +#define AVS_VMOD_100_OPP 0xA +#define AVS_VMOD_50_OPP 0xB +#define AVS_VSAFE 0xC +#define AVS_VSAFE_RET 0xD +#define AVS_SIZE 14 + +static int avs_read(struct seq_file *s, void *p) +{ + + u8 avs[AVS_SIZE]; + void __iomem *tcdm_base; + + if (cpu_is_u8500()) { + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); + + memcpy_fromio(avs, tcdm_base + PRCM_AVS_BASE, AVS_SIZE); + + seq_printf(s, "VBB_RET : 0x%02x\n", avs[AVS_VBB_RET]); + seq_printf(s, "VBB_MAX_OPP : 0x%02x\n", avs[AVS_VBB_MAX_OPP]); + seq_printf(s, "VBB_100_OPP : 0x%02x\n", avs[AVS_VBB_100_OPP]); + seq_printf(s, "VBB_50_OPP : 0x%02x\n", avs[AVS_VBB_50_OPP]); + seq_printf(s, "VARM_MAX_OPP : 0x%02x\n", avs[AVS_VARM_MAX_OPP]); + seq_printf(s, "VARM_100_OPP : 0x%02x\n", avs[AVS_VARM_100_OPP]); + seq_printf(s, "VARM_50_OPP : 0x%02x\n", avs[AVS_VARM_50_OPP]); + seq_printf(s, "VARM_RET : 0x%02x\n", avs[AVS_VARM_RET]); + seq_printf(s, "VAPE_100_OPP : 0x%02x\n", avs[AVS_VAPE_100_OPP]); + seq_printf(s, "VAPE_50_OPP : 0x%02x\n", avs[AVS_VAPE_50_OPP]); + seq_printf(s, "VMOD_100_OPP : 0x%02x\n", avs[AVS_VMOD_100_OPP]); + seq_printf(s, "VMOD_50_OPP : 0x%02x\n", avs[AVS_VMOD_50_OPP]); + seq_printf(s, "VSAFE : 0x%02x\n", avs[AVS_VSAFE]); + seq_printf(s, "VSAFE_RET : 0x%02x\n", avs[AVS_VSAFE_RET]); + } else { + seq_printf(s, "Only u8500 supported.\n"); + } + + return 0; +} + +static void prcmu_data_mem_print(struct seq_file *s) +{ + int i; + int err; + void __iomem *tcdm_base; + u32 dmem[4]; + + if (cpu_is_u8500()) { + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); + + for (i = 0; i < U8500_PRCMU_TCDM_SIZE; i += 16) { + dmem[0] = readl(tcdm_base + i + 0); + dmem[1] = readl(tcdm_base + i + 4); + dmem[2] = readl(tcdm_base + i + 8); + dmem[3] = readl(tcdm_base + i + 12); + + if (s) { + err = seq_printf(s, + "0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n", + ((int)tcdm_base) + i, dmem[0], + dmem[1], dmem[2], dmem[3]); + if (err < 0) { + pr_err("%s: seq_printf overflow, addr=%x\n", + __func__, ((int)tcdm_base) + i); + /* Can't do much here */ + return; + } + } else { + printk(KERN_INFO + "0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n", + ((int)tcdm_base) + i, dmem[0], + dmem[1], dmem[2], dmem[3]); + } + } + } +} + +void prcmu_debug_dump_data_mem(void) +{ + printk(KERN_INFO "PRCMU data memory dump:\n"); + prcmu_data_mem_print(NULL); +} + +static int prcmu_debugfs_data_mem_read(struct seq_file *s, void *p) +{ + seq_printf(s, "PRCMU data memory:\n"); + prcmu_data_mem_print(s); + + return 0; +} + +static void prcmu_regs_print(struct seq_file *s) +{ + int i; + int err; + void __iomem *prcmu_base; + u32 reg_val; + + if (cpu_is_u8500()) { + prcmu_base = __io_address(U8500_PRCMU_BASE); + + for (i = 0; i < ARRAY_SIZE(u8500_prcmu_dump_regs); i++) { + reg_val = readl(prcmu_base + + u8500_prcmu_dump_regs[i]); + + if (s) { + err = seq_printf(s, "0x%04x: 0x%08x\n", + u8500_prcmu_dump_regs[i], reg_val); + if (err < 0) { + pr_err("%s: seq_printf overflow," + "offset=%x\n", __func__, + u8500_prcmu_dump_regs[i]); + /* Can't do much here */ + return; + } + } else { + printk(KERN_INFO + "0x%04x: 0x%08x\n", + u8500_prcmu_dump_regs[i], reg_val); + } + } + } +} + +static void prcmu_secure_regs_print(struct seq_file *s) +{ + int i; + int err; + void __iomem *prcmu_sec_base; + u32 reg_val; + + if (cpu_is_u8500()) { + /* PRCMU secure base starts after SZ_4K */ + prcmu_sec_base = ioremap(U8500_PRCMU_BASE + SZ_4K, SZ_4K); + if (!prcmu_sec_base) { + pr_err("%s: ioremap faild\n", __func__); + return; + } + + for (i = 0; i < ARRAY_SIZE(u8500_prcmu_dump_secure_regs); i++) { + reg_val = readl(prcmu_sec_base + + u8500_prcmu_dump_secure_regs[i]); + + if (s) { + err = seq_printf(s, "0x%04x: 0x%08x\n", + u8500_prcmu_dump_secure_regs[i] + + SZ_4K, + reg_val); + if (err < 0) { + pr_err("%s: seq_printf overflow," + "offset=%x\n", __func__, + u8500_prcmu_dump_secure_regs[i] + + SZ_4K); + /* Can't do much here */ + break; + } + } else { + printk(KERN_INFO + "0x%04x: 0x%08x\n", + u8500_prcmu_dump_secure_regs[i] + + SZ_4K, + reg_val); + } + } + + iounmap(prcmu_sec_base); + } +} + +void prcmu_debug_dump_regs(void) +{ + printk(KERN_INFO "PRCMU registers dump:\n"); + prcmu_regs_print(NULL); + prcmu_secure_regs_print(NULL); +} + +static int prcmu_debugfs_regs_read(struct seq_file *s, void *p) +{ + seq_printf(s, "PRCMU registers:\n"); + prcmu_regs_print(s); + prcmu_secure_regs_print(s); + return 0; +} + +/* Interrupt debugging */ + +/* There are eight mailboxes */ +#define NUM_MAILBOXES 8 +#define NUM_MAILBOX0_EVENTS 32 +static u32 num_mailbox_interrupts[NUM_MAILBOXES]; +static u32 num_mailbox0_events[NUM_MAILBOX0_EVENTS]; +static u32 num_mailbox0_events_garbage[NUM_MAILBOX0_EVENTS]; + +void prcmu_debug_register_interrupt(u32 mailbox) +{ + if (mailbox < NUM_MAILBOXES) + num_mailbox_interrupts[mailbox]++; +} + +void prcmu_debug_register_mbox0_event(u32 ev, u32 mask) +{ + int i; + + for (i = 0 ; i < NUM_MAILBOX0_EVENTS; i++) + if (ev & (1 << i)) { + if (mask & (1 << i)) + num_mailbox0_events[i]++; + else + num_mailbox0_events_garbage[i]++; + } +} + +static int interrupt_read(struct seq_file *s, void *p) +{ + int i; + char **mbox0names; + + static char *mbox0names_u8500[] = { + "RTC", + "RTT0", + "RTT1", + "HSI0", + "HSI1", + "CA_WAKE", + "USB", + "ABB", + "ABB_FIFO", + "SYSCLK_OK", + "CA_SLEE", + "AC_WAKE_ACK", + "SIDE_TONE_OK", + "ANC_OK", + "SW_ERROR", + "AC_SLEEP_ACK", + NULL, + "ARM", + "HOTMON_LOW", + "HOTMON_HIGH", + "MODEM_SW_RESET_REQ", + NULL, + NULL, + "GPIO0", + "GPIO1", + "GPIO2", + "GPIO3", + "GPIO4", + "GPIO5", + "GPIO6", + "GPIO7", + "GPIO8"}; + static char *mbox0names_u5500[] = { + "RTC", + "RTT0", + "RTT1", + "CD_IRQ", + "SRP_TIM", + "APE_REQ", + "USB", + "ABB", + "LOW_POWER_AUDIO", + "TEMP_SENSOR_LOW", + "ARM", + "AC_WAKE_ACK", + NULL, + "TEMP_SENSOR_HIGH", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "MODEM_SW_RESET_REQ", + NULL, + NULL, + "GPIO0", + "GPIO1", + "GPIO2", + "GPIO3", + "GPIO4", + "GPIO5", + "GPIO6", + "GPIO7", + "AC_REL_ACK"}; + + if (cpu_is_u8500()) { + mbox0names = mbox0names_u8500; + } else if (cpu_is_u5500()) { + mbox0names = mbox0names_u5500; + } else { + seq_printf(s, "Unknown ASIC!\n"); + return 0; + } + + seq_printf(s, "mailbox0: %d\n", num_mailbox_interrupts[0]); + + for (i = 0; i < NUM_MAILBOX0_EVENTS; i++) + if (mbox0names[i]) { + seq_printf(s, " %20s %d ", mbox0names[i], + num_mailbox0_events[i] + ); + if (num_mailbox0_events_garbage[i]) + seq_printf(s, "unwanted: %d", + num_mailbox0_events_garbage[i]); + seq_printf(s, "\n"); + } else if (num_mailbox0_events[i]) { + seq_printf(s, " unknown (%d) %d\n", + i, num_mailbox0_events[i]); + } + + for (i = 1 ; i < NUM_MAILBOXES; i++) + seq_printf(s, "mailbox%d: %d\n", i, num_mailbox_interrupts[i]); + return 0; +} + +static int opp_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, opp_read, inode->i_private); +} + +static int ape_stats_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, ape_stats_print, inode->i_private); +} + +static int ddr_stats_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, ddr_stats_print, inode->i_private); +} + +static int arm_stats_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, arm_stats_print, inode->i_private); +} + +static int cpufreq_delay_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, cpufreq_delay_read, inode->i_private); +} + +static int ape_voltage_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, ape_voltage_read, inode->i_private); +} + +static int avs_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, avs_read, inode->i_private); +} + +static int prcmu_data_mem_open_file(struct inode *inode, struct file *file) +{ + int err; + struct seq_file *s; + + err = single_open(file, prcmu_debugfs_data_mem_read, inode->i_private); + if (!err) { + /* Default buf size in seq_read is not enough */ + s = (struct seq_file *)file->private_data; + s->size = (PAGE_SIZE * 4); + s->buf = kmalloc(s->size, GFP_KERNEL); + if (!s->buf) { + single_release(inode, file); + err = -ENOMEM; + } + } + return err; +} + +static int prcmu_regs_open_file(struct inode *inode, struct file *file) +{ + int err; + struct seq_file *s; + + err = single_open(file, prcmu_debugfs_regs_read, inode->i_private); + if (!err) { + /* Default buf size in seq_read is not enough */ + s = (struct seq_file *)file->private_data; + s->size = (PAGE_SIZE * 2); + s->buf = kmalloc(s->size, GFP_KERNEL); + if (!s->buf) { + single_release(inode, file); + err = -ENOMEM; + } + } + return err; +} + +static int interrupt_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, interrupt_read, inode->i_private); +} + +static const struct file_operations opp_fops = { + .open = opp_open_file, + .write = opp_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ape_stats_fops = { + .open = ape_stats_open_file, + .write = ape_stats_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ddr_stats_fops = { + .open = ddr_stats_open_file, + .write = ddr_stats_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations arm_stats_fops = { + .open = arm_stats_open_file, + .write = arm_stats_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations cpufreq_delay_fops = { + .open = cpufreq_delay_open_file, + .write = cpufreq_delay_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ape_voltage_fops = { + .open = ape_voltage_open_file, + .write = ape_voltage_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations avs_fops = { + .open = avs_open_file, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations prcmu_data_mem_fops = { + .open = prcmu_data_mem_open_file, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations prcmu_regs_fops = { + .open = prcmu_regs_open_file, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations interrupts_fops = { + .open = interrupt_open_file, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int setup_debugfs(void) +{ + struct dentry *dir; + struct dentry *file; + + dir = debugfs_create_dir("prcmu", NULL); + if (IS_ERR_OR_NULL(dir)) + goto fail; + + file = debugfs_create_file("ape_stats", (S_IRUGO | S_IWUGO), + dir, NULL, &ape_stats_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("ddr_stats", (S_IRUGO | S_IWUGO), + dir, NULL, &ddr_stats_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("arm_stats", (S_IRUGO | S_IWUGO), + dir, NULL, &arm_stats_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("ape_opp", (S_IRUGO), + dir, (void *)&ape_sh, + &opp_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("ddr_opp", (S_IRUGO), + dir, (void *)&ddr_sh, + &opp_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("arm_opp", (S_IRUGO), + dir, (void *)&arm_sh, + &opp_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("opp_cpufreq_delay", (S_IRUGO), + dir, NULL, &cpufreq_delay_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("ape_voltage", (S_IRUGO), + dir, NULL, &ape_voltage_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("avs", + (S_IRUGO), + dir, NULL, &avs_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("data_mem", (S_IRUGO), + dir, NULL, + &prcmu_data_mem_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("regs", (S_IRUGO), + dir, NULL, + &prcmu_regs_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + file = debugfs_create_file("interrupts", + (S_IRUGO), + dir, NULL, &interrupts_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + + return 0; +fail: + if (!IS_ERR_OR_NULL(dir)) + debugfs_remove_recursive(dir); + + pr_err("prcmu debug: debugfs entry failed\n"); + return -ENOMEM; +} + +static __init int prcmu_debug_init(void) +{ + spin_lock_init(&ape_sh.lock); + spin_lock_init(&ddr_sh.lock); + spin_lock_init(&arm_sh.lock); + ape_sh.start = ktime_get(); + ddr_sh.start = ktime_get(); + arm_sh.start = ktime_get(); + return 0; +} +arch_initcall(prcmu_debug_init); + +static __init int prcmu_debug_debugfs_init(void) +{ + setup_debugfs(); + return 0; +} +late_initcall(prcmu_debug_debugfs_init); diff --git a/arch/arm/mach-ux500/product.c b/arch/arm/mach-ux500/product.c new file mode 100644 index 00000000000..f4647b3ab29 --- /dev/null +++ b/arch/arm/mach-ux500/product.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Jens Wiklander <jens.wiklander@stericsson.com> + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> + * + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/tee.h> +#include <linux/module.h> +#include <mach/hardware.h> +#include <asm/mach-types.h> + +#define STATIC_TEE_TA_START_LOW 0xBC765EDE +#define STATIC_TEE_TA_START_MID 0x6724 +#define STATIC_TEE_TA_START_HIGH 0x11DF +#define STATIC_TEE_TA_START_CLOCKSEQ \ + {0x8E, 0x12, 0xEC, 0xDB, 0xDF, 0xD7, 0x20, 0x85} + +#define U5500_PRCMU_DBG_PWRCTRL (U5500_PRCMU_BASE + 0x4AC) +#define PRCMU_DBG_PWRCTRL_A9DBGCLKEN (1 << 4) + +static struct tee_product_config product_config; + +bool ux500_jtag_enabled(void) +{ +#ifdef CONFIG_UX500_DEBUG_NO_LAUTERBACH + return false; +#else + if (machine_is_snowball()) + return true; + if (cpu_is_u5500()) + return readl_relaxed(__io_address(U5500_PRCMU_DBG_PWRCTRL)) + & PRCMU_DBG_PWRCTRL_A9DBGCLKEN; + + if (cpu_is_u8500() || cpu_is_u9540()) + return (product_config.rt_flags & TEE_RT_FLAGS_JTAG_ENABLED) == + TEE_RT_FLAGS_JTAG_ENABLED; + + return true; +#endif +} + +static int __init product_detect(void) +{ + int err; + int origin_err; + struct tee_operation operation = { { { 0 } } }; + struct tee_context context; + struct tee_session session; + + /* Selects trustzone application needed for the job. */ + struct tee_uuid static_uuid = { + STATIC_TEE_TA_START_LOW, + STATIC_TEE_TA_START_MID, + STATIC_TEE_TA_START_HIGH, + STATIC_TEE_TA_START_CLOCKSEQ, + }; + + if (cpu_is_u5500()) + return -ENODEV; + + err = teec_initialize_context(NULL, &context); + if (err) { + pr_err("ux500-product: unable to initialize tee context," + " err = %d\n", err); + err = -EINVAL; + goto error0; + } + + err = teec_open_session(&context, &session, &static_uuid, + TEEC_LOGIN_PUBLIC, NULL, NULL, &origin_err); + if (err) { + pr_err("ux500-product: unable to open tee session," + " tee error = %d, origin error = %d\n", + err, origin_err); + err = -EINVAL; + goto error1; + } + + operation.shm[0].buffer = &product_config; + operation.shm[0].size = sizeof(product_config); + operation.shm[0].flags = TEEC_MEM_OUTPUT; + operation.flags = TEEC_MEMREF_0_USED; + + err = teec_invoke_command(&session, + TEE_STA_GET_PRODUCT_CONFIG, + &operation, &origin_err); + if (err) { + pr_err("ux500-product: fetching product settings failed, err=%d", + err); + err = -EINVAL; + goto error1; + } + + switch (product_config.product_id) { + case TEE_PRODUCT_ID_8400: + pr_info("ux500-product: u8400 detected\n"); + break; + case TEE_PRODUCT_ID_8500: + pr_info("ux500-product: u8500 detected\n"); + break; + case TEE_PRODUCT_ID_9500: + pr_info("ux500-product: u9500 detected\n"); + break; + case TEE_PRODUCT_ID_5500: + pr_info("ux500-product: u5500 detected\n"); + break; + case TEE_PRODUCT_ID_7400: + pr_info("ux500-product: u7400 detected\n"); + break; + case TEE_PRODUCT_ID_8500C: + pr_info("ux500-product: u8500C detected\n"); + break; + case TEE_PRODUCT_ID_UNKNOWN: + default: + pr_info("ux500-product: UNKNOWN! (0x%x) detected\n", + product_config.product_id); + break; + } + pr_info("ux500-product: JTAG is %s\n", + ux500_jtag_enabled() ? "enabled" : "disabled"); +error1: + (void) teec_finalize_context(&context); +error0: + return err; +} +device_initcall(product_detect); diff --git a/arch/arm/mach-ux500/product.h b/arch/arm/mach-ux500/product.h new file mode 100644 index 00000000000..502eff4df14 --- /dev/null +++ b/arch/arm/mach-ux500/product.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Jens Wiklander <jens.wiklander@stericsson.com> + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> + * + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#ifndef UX500_PRODUCT_H +#define UX500_PRODUCT_H + +#ifdef CONFIG_TEE_UX500 + +bool ux500_jtag_enabled(void); + +#else + +static inline bool ux500_jtag_enabled(void) +{ + return true; +} + +#endif +#endif diff --git a/arch/arm/mach-ux500/regulator-u5500.h b/arch/arm/mach-ux500/regulator-u5500.h new file mode 100644 index 00000000000..cf3eeed9366 --- /dev/null +++ b/arch/arm/mach-ux500/regulator-u5500.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + */ + +#ifndef __REGULATOR_U5500_H +#define __REGULATOR_U5500_H + +enum u5500_regulator_id { + U5500_REGULATOR_VAPE, + U5500_REGULATOR_SWITCH_SGA, + U5500_REGULATOR_SWITCH_HVA, + U5500_REGULATOR_SWITCH_SIA, + U5500_REGULATOR_SWITCH_DISP, + U5500_REGULATOR_SWITCH_ESRAM12, + U5500_NUM_REGULATORS +}; + +#endif diff --git a/arch/arm/mach-ux500/test/Kconfig b/arch/arm/mach-ux500/test/Kconfig new file mode 100644 index 00000000000..a071166d092 --- /dev/null +++ b/arch/arm/mach-ux500/test/Kconfig @@ -0,0 +1,6 @@ + +config DB8500_PWR_TEST + bool "Power usage module test" + depends on (UX500_SOC_DB8500 && DEBUG_FS && REGULATOR_AB8500_DEBUG) + help + Add power module tests for idle diff --git a/arch/arm/mach-ux500/test/Makefile b/arch/arm/mach-ux500/test/Makefile new file mode 100644 index 00000000000..58f1f2f3be6 --- /dev/null +++ b/arch/arm/mach-ux500/test/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_DB8500_PWR_TEST) += pwr.o diff --git a/arch/arm/mach-ux500/test/pwr.c b/arch/arm/mach-ux500/test/pwr.c new file mode 100644 index 00000000000..5d5d24a38ab --- /dev/null +++ b/arch/arm/mach-ux500/test/pwr.c @@ -0,0 +1,828 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson + * + * License terms: GNU General Public License (GPL) version 2 + * + * This is a module test for clocks and regulators. + */ + +#include <linux/module.h> +#include <linux/debugfs.h> +#include <linux/delay.h> +#include <linux/seq_file.h> +#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/mfd/abx500/ab8500-sysctrl.h> +#include <linux/mfd/dbx500-prcmu.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/db8500-prcmu.h> + +#include <mach/hardware.h> +#include <mach/pm.h> + +#include "../../../drivers/regulator/dbx500-prcmu.h" +#include "../../../drivers/regulator/ab8500-debug.h" + +#define PRCC_PCKSR 0x010 +#define PRCC_KCKSR 0x014 + +#define PRCM_PLLSOC0_ENABLE 0x090 +#define PRCM_PLLSOC1_ENABLE 0x094 +#define PRCM_PLL32K_ENABLE 0x10C +#define PRCM_PLLARM_ENABLE 0x098 +#define PRCM_PLLDDR_ENABLE 0x09C +#define PRCM_RNG_ENABLE 0x50C +#define PRCM_PLLDSI_ENABLE 0x504 + +#define PRCM_CLKOCR 0x1CC + +#define PRCM_ARMCLKFIX_MGT 0x000 +#define PRCM_ACLK_MGT 0x004 +#define PRCM_SGACLK_MGT 0x014 +#define PRCM_UARTCLK_MGT 0x018 +#define PRCM_MSP02CLK_MGT 0x01C +#define PRCM_MSP1CLK_MGT 0x288 +#define PRCM_I2CCLK_MGT 0x020 +#define PRCM_SDMMCCLK_MGT 0x024 +#define PRCM_SLIMCLK_MGT 0x028 +#define PRCM_PER1CLK_MGT 0x02C +#define PRCM_PER2CLK_MGT 0x030 +#define PRCM_PER3CLK_MGT 0x034 +#define PRCM_PER5CLK_MGT 0x038 +#define PRCM_PER6CLK_MGT 0x03C +#define PRCM_PER7CLK_MGT 0x040 +#define PRCM_LCDCLK_MGT 0x044 +#define PRCM_BMLCLK_MGT 0x04C +#define PRCM_HSITXCLK_MGT 0x050 +#define PRCM_HSIRXCLK_MGT 0x054 +#define PRCM_HDMICLK_MGT 0x058 +#define PRCM_APEATCLK_MGT 0x05C +#define PRCM_APETRACECLK_MGT 0x060 +#define PRCM_MCDECLK_MGT 0x064 +#define PRCM_IPI2CCLK_MGT 0x068 +#define PRCM_DSIALTCLK_MGT 0x06C +#define PRCM_SPARE2CLK_MGT 0x070 +#define PRCM_SPARE1CLK_MGT 0x048 +#define PRCM_DMACLK_MGT 0x074 +#define PRCM_B2R2CLK_MGT 0x078 +#define PRCM_TVCLK_MGT 0x07C +#define PRCM_SSPCLK_MGT 0x280 +#define PRCM_RNGCLK_MGT 0x284 +#define PRCM_UICCCLK_MGT 0x27C + +#define PRCM_DSITVCLK_DIV 0x52C +#define PRCM_DSI_PLLOUT_SEL 0x530 + +#define PRCM_YYCLKEN0_MGT_VAL 0x520 + +enum acc_type { + RAW = 0, + CLK_PRCMU, + CLK_PAR_PRCMU, + CLK_ABB_SYS, + REG_DB8500, + REG_AB8500, +}; + +struct pwr_test { + enum acc_type type; + u32 base; + u32 off; + u32 mask; + u32 val; + + u32 par_off; + u32 par_mask; + u32 par_val; + + char *txt; + char *txt2; + + /* For AB8500 */ + enum ab8500_regulator_mode mode; + enum ab8500_regulator_hwmode hwmode; + enum hwmode_auto hwmode_auto[4]; + int volt_selected; + int alt_volt_selected; + int volt_len; + int volt[4]; + int alt_volt[4]; +}; + +#define RAW_TEST(_base, _off, _mask, _val) \ + { \ + .type = RAW, \ + .base = _base, \ + .off = _off, \ + .mask = _mask, \ + .val = _val, \ + .txt = #_base, \ + .txt2 = #_off \ + } + +#define CLK_TEST_PAR_PRCMU(_base, _off, _mask, _val, _par_off, \ + _par_mask, _par_val) \ + { \ + .type = CLK_PAR_PRCMU, \ + .base = _base, \ + .off = _off, \ + .mask = _mask, \ + .val = _val, \ + .par_off = _par_off, \ + .par_mask = _par_mask, \ + .par_val = _par_val, \ + .txt = #_base, \ + .txt2 = #_off \ + } + +#define CLK_TEST_PRCMU(_off, _mask, _val) \ + { \ + .type = CLK_PRCMU, \ + .off = _off, \ + .mask = _mask, \ + .val = _val, \ + .txt = #_off, \ + } + +#define CLK_TEST_ABB_SYS(_off, _mask, _val) \ + { \ + .type = CLK_ABB_SYS, \ + .off = _off, \ + .mask = _mask, \ + .val = _val, \ + .txt = #_off, \ + } +#define REG_TEST_DB8500(_reg, _val) \ + { \ + .type = REG_DB8500, \ + .off = _reg, \ + .val = _val, \ + } + + +static struct u8500_regulators +{ + struct dbx500_regulator_info *db8500_reg; + int db8500_num; +} u8500_reg; + +/* + * Idle - Note: this is not suspend. + * This test shall pass when the screen is black, before + * suspend is executed. + */ + +static struct pwr_test idle_test[] = { + + /* Test all periph kernel and bus clocks */ + /* bus: gpioctrl */ + CLK_TEST_PAR_PRCMU(U8500_CLKRST1_BASE, PRCC_PCKSR, 0x07ff, BIT(9), + PRCM_PER1CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PAR_PRCMU(U8500_CLKRST1_BASE, PRCC_KCKSR, 0x037f, 0x0000, + PRCM_PER1CLK_MGT, BIT(8), BIT(8)), + /* bus: gpioctrl */ + CLK_TEST_PAR_PRCMU(U8500_CLKRST2_BASE, PRCC_PCKSR, 0x0fff, BIT(11), + PRCM_PER2CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PAR_PRCMU(U8500_CLKRST2_BASE, PRCC_KCKSR, 0x00ff, 0x0000, + PRCM_PER2CLK_MGT, BIT(8), BIT(8)), + /* bus: uart2, gpioctrl - users??, kernel: uart2 */ + CLK_TEST_PAR_PRCMU(U8500_CLKRST3_BASE, PRCC_PCKSR, 0x01ff, BIT(8) | BIT(6), + PRCM_PER3CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PAR_PRCMU(U8500_CLKRST3_BASE, PRCC_KCKSR, 0x00fe, BIT(6), + PRCM_PER3CLK_MGT, BIT(8), BIT(8)), + /* No user on periph5 */ + CLK_TEST_PAR_PRCMU(U8500_CLKRST5_BASE, PRCC_PCKSR, 0x0003, 0x0000, + PRCM_PER5CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PAR_PRCMU(U8500_CLKRST5_BASE, PRCC_KCKSR, 0x0000, 0x0000, + PRCM_PER5CLK_MGT, BIT(8), BIT(8)), + /* bus: MTU0 used for scheduling ApIdle */ + CLK_TEST_PAR_PRCMU(U8500_CLKRST6_BASE, PRCC_PCKSR, 0x00ff, BIT(6), + PRCM_PER6CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PAR_PRCMU(U8500_CLKRST6_BASE, PRCC_KCKSR, 0x0001, 0x0000, + PRCM_PER6CLK_MGT, BIT(8), BIT(8)), + + /* Test that clkout 1/2 is off */ + CLK_TEST_PRCMU(PRCM_CLKOCR, 0x3f003f, 0x0000), + + /* Test that ulp clock is off */ + CLK_TEST_ABB_SYS(AB8500_SYSULPCLKCTRL1, 0xfc, 0x00), + + /* Test that prcm clks are in proper state */ + CLK_TEST_PRCMU(PRCM_ARMCLKFIX_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_ACLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_SGACLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_UARTCLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_MSP02CLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_MSP1CLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_I2CCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_SDMMCCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_SLIMCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_PER1CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_PER2CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_PER3CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_PER5CLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_PER6CLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_PER7CLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_LCDCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_BMLCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_HSITXCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_HSIRXCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_HDMICLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_APEATCLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_APETRACECLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_MCDECLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_IPI2CCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_DSIALTCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_DMACLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_B2R2CLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_TVCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_SSPCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_RNGCLK_MGT, BIT(8), BIT(8)), + CLK_TEST_PRCMU(PRCM_UICCCLK_MGT, BIT(8), 0x000), + CLK_TEST_PRCMU(PRCM_DSITVCLK_DIV, BIT(24) | BIT(25) | BIT(26), + 0x000), + CLK_TEST_PRCMU(PRCM_DSI_PLLOUT_SEL, (BIT(0) | BIT(1) | BIT(2) | + BIT(8) | BIT(9) | BIT(10)), + 0x200), /* Will change */ + CLK_TEST_PRCMU(PRCM_YYCLKEN0_MGT_VAL, 0xBFFFFFFF, + (BIT(27) | BIT(23) | BIT(22) | BIT(15) | + BIT(13) | BIT(12) | BIT(11) | BIT(5) | + BIT(1) | BIT(0))), + + /* Check db8500 regulator settings - enable */ + REG_TEST_DB8500(DB8500_REGULATOR_VAPE, 0), + REG_TEST_DB8500(DB8500_REGULATOR_VARM, 0), + REG_TEST_DB8500(DB8500_REGULATOR_VMODEM, 0), + REG_TEST_DB8500(DB8500_REGULATOR_VPLL, 0), + REG_TEST_DB8500(DB8500_REGULATOR_VSMPS1, 0), + REG_TEST_DB8500(DB8500_REGULATOR_VSMPS2, 1), + REG_TEST_DB8500(DB8500_REGULATOR_VSMPS3, 0), + REG_TEST_DB8500(DB8500_REGULATOR_VRF1, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SVAMMDSP, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SVAMMDSPRET, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SVAPIPE, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SIAMMDSP, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SIAMMDSPRET, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SIAPIPE, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_SGA, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_B2R2_MCDE, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_ESRAM12, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_ESRAM12RET, 0), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_ESRAM34, 1), + REG_TEST_DB8500(DB8500_REGULATOR_SWITCH_ESRAM34RET, 0), + + /* ab8500 regulators */ + { + .type = REG_AB8500, + .off = AB8500_VARM, + .mode = AB8500_MODE_ON, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_INVAL, HWM_INVAL, HWM_OFF}, + .volt_selected = 2, + /* Voltage and voltage selection depends on ARM_OPP */ + .alt_volt_selected = 1, + .volt_len = 3, + .volt = {1350000, 1025000, 750000}, + .alt_volt = {1250000, 1025000, 750000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VBBP, + .mode = AB8500_MODE_ON, + .hwmode_auto = {HWM_OFF, HWM_INVAL, HWM_INVAL, HWM_INVAL}, + .volt_selected = 1, + .volt_len = 2, + .volt = {-300000, 0}, + }, + { + .type = REG_AB8500, + .off = AB8500_VBBN, + .mode = AB8500_MODE_ON, + .hwmode_auto = {HWM_OFF, HWM_INVAL, HWM_INVAL, HWM_INVAL}, + .volt_selected = 1, + .volt_len = 2, + .volt = {300000, 0}, + }, + { + .type = REG_AB8500, + .off = AB8500_VAPE, + .mode = AB8500_MODE_ON, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_INVAL, HWM_INVAL, HWM_OFF}, + .volt_selected = 2, + /* APE_OPP can get changes by cpufreq */ + .alt_volt_selected = 1, + .volt_len = 3, + .volt = {1225000, 1000000, 1200000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VSMPS1, + .mode = AB8500_MODE_HW, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_ON, HWM_OFF, HWM_OFF, HWM_OFF}, + .volt_selected = 2, + .volt_len = 3, + .volt = {1200000, 1200000, 1200000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VSMPS2, + .mode = AB8500_MODE_HW, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_ON, HWM_ON, HWM_ON, HWM_OFF}, + .volt_selected = 2, + .volt_len = 3, + .volt = {1800000, 1800000, 1800000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VSMPS3, + .mode = AB8500_MODE_HW, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_ON, HWM_OFF, HWM_OFF, HWM_OFF}, + .volt_selected = 2, + .volt_len = 3, + .volt = {925000, 1212500, 1200000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VPLL, + .mode = AB8500_MODE_HW, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_ON, HWM_OFF, HWM_OFF, HWM_OFF}, + }, + { + .type = REG_AB8500, + .off = AB8500_VREFDDR, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VMOD, + .mode = AB8500_MODE_OFF, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + .volt_selected = 2, + .volt_len = 2, + .volt = {1125000, 1025000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VEXTSUPPLY1, + .mode = AB8500_MODE_LP, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + }, + { + .type = REG_AB8500, + .off = AB8500_VEXTSUPPLY2, + .mode = AB8500_MODE_OFF, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + }, + { + .type = REG_AB8500, + .off = AB8500_VEXTSUPPLY3, + .mode = AB8500_MODE_ON, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_ON, HWM_OFF, HWM_ON, HWM_OFF}, + }, + { + .type = REG_AB8500, + .off = AB8500_VRF1, + .mode = AB8500_MODE_HW, + .volt_len = 1, + .volt = {2150000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VANA, + .mode = AB8500_MODE_OFF, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + }, + { + .type = REG_AB8500, + .off = AB8500_VAUX1, + .mode = AB8500_MODE_ON, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + .volt_len = 1, + .volt = {2800000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VAUX2, + .mode = AB8500_MODE_ON, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + .volt_len = 1, + .volt = {3300000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VAUX3, + .mode = AB8500_MODE_OFF, + .hwmode = AB8500_HWMODE_HPLP, + .hwmode_auto = {HWM_OFF, HWM_OFF, HWM_OFF, HWM_OFF}, + .volt_len = 1, + .volt = {2910000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VINTCORE, + .mode = AB8500_MODE_OFF, + .volt_len = 1, + .volt = {1250000}, + }, + { + .type = REG_AB8500, + .off = AB8500_VTVOUT, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VAUDIO, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VANAMIC1, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VANAMIC2, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VDMIC, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VUSB, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VOTG, + .mode = AB8500_MODE_OFF, + }, + { + .type = REG_AB8500, + .off = AB8500_VBUSBIS, + .mode = AB8500_MODE_OFF, + }, +}; + +static int read_raw(struct pwr_test *t) +{ + u32 res; + int i; + + for (i = 0 ; i < 50; i++) { + res = readl(__io_address(t->base) + t->off); + if ((res & t->mask) == t->val) + return 0; + msleep(10); + } + + pr_err("pwr_test: ERROR: %s %s 0x%x, 0x%x reads 0x%x (masked: 0x%x), " + "expected 0x%x (mask: 0x%x)\n", + t->txt, t->txt2, t->base, t->off, res, + res & t->mask, t->val, t->mask); + return -EINVAL; +} + +static int clk_read_par_prcmu(struct pwr_test *t) + { + u32 res; + int i; + bool parent_enabled = false; + + /* check if parent clock is in expected configuration (usually PRCC) */ + for (i = 0 ; i < 50; i++) { + res = prcmu_read(t->par_off); + if ((res & t->par_mask) == t->par_val) { + parent_enabled = true; + break; + } + msleep(10); + } + + /* If parent clock is off, but clock is expected to be on --> fail */ + if (!parent_enabled && t->val != 0) { + pr_err("pwr_test: ERROR: PRCMU parent clk of %s, " + "0x%x reads 0x%x (masked: 0x%x), " + "expected to be on 0x%x (mask: 0x%x)\n", + t->txt, t->par_off, res, res & t->par_mask, + t->par_val, t->par_mask); + return -EINVAL; + } + + /* It's ok if parent clock is off and clock is off as well */ + if (!parent_enabled && t->val == 0) + return 0; + + return read_raw(t); +} + +static int clk_read_prcmu(struct pwr_test *t) +{ + u32 res; + int i; + + for (i = 0 ; i < 50; i++) { + res = prcmu_read(t->off); + if ((res & t->mask) == t->val) + return 0; + msleep(10); + } + + pr_err("pwr_test: ERROR: %s PRCMU, 0x%x reads 0x%x (masked: 0x%x), " + "expected 0x%x (mask: 0x%x)\n", + t->txt, t->off, res, res & t->mask, t->val, t->mask); + return -EINVAL; +} + +static int clk_read_abb_sys(struct pwr_test *t) +{ + int ret; + u8 val = 0; + int i; + + for (i = 0; i < 50; i++) { + ret = ab8500_sysctrl_read(t->off, &val); + if (ret < 0) { + pr_err("pwr_test: AB8500 access error: %d of " + "reg: 0x%x\n", ret, t->off); + return ret; + } + if ((val & (u8)t->mask) == t->val) + return 0; + msleep(10); + } + + pr_err("pwr_test: ERROR: AB8500 register 0x%x %s, reads 0x%x," + " (masked 0x%x) expected 0x%x (mask: 0x%x)\n", + t->base, t->txt, val, val & (u8)t->mask, t->val, t->mask); + + return -EINVAL; +} + +static int reg_read_db8500(struct pwr_test *t) +{ + int i, j; + + for (j = 0 ; j < u8500_reg.db8500_num ; j++) + if (u8500_reg.db8500_reg[j].desc.id == t->off) + break; + + if (j == u8500_reg.db8500_num) { + pr_err("pwr_test: Invalid db8500 regulator\n"); + return -EINVAL; + } + + for (i = 0; i < 50; i++) { + + /* powerstate is a special case */ + if (t->off == DB8500_REGULATOR_VAPE) { + if ((u8500_reg.db8500_reg[j].is_enabled || + power_state_active_is_enabled()) == t->val) + return 0; + } else { + if (u8500_reg.db8500_reg[j].is_enabled == t->val) + return 0; + } + msleep(10); + } + + pr_err("pwr_test: ERROR: DB8500 regulator %s is 0x%x expected 0x%x\n", + u8500_reg.db8500_reg[j].desc.name, + t->off != DB8500_REGULATOR_VAPE ? + u8500_reg.db8500_reg[j].is_enabled : + u8500_reg.db8500_reg[j].is_enabled || + power_state_active_is_enabled(), + t->val); + + return -EINVAL; +} + +static int reg_read_ab8500(struct pwr_test *t) +{ + int i, j; + int ret; + struct ab8500_debug_regulator_status s; + + for (i = 0; i < 50; i++) { + ret = ab8500_regulator_debug_read(t->off, &s); + + if (ret) { + pr_err("pwr_test: Fail to read ab8500 regulator\n"); + return -EINVAL; + } + + if (t->mode != s.mode) + goto repeat; + + if (t->hwmode != s.hwmode) + goto repeat; + + if (t->volt_selected != s.volt_selected && + t->alt_volt_selected != s.volt_selected) + goto repeat; + + if (t->volt_len != s.volt_len) + goto repeat; + + for (j = 0; j < 4 && s.hwmode != AB8500_HWMODE_NONE; j++) + if (s.hwmode_auto[j] != t->hwmode_auto[j]) + goto repeat; + + for (j = 0; j < s.volt_len; j++) + if (s.volt[j] != t->volt[j] && + s.volt[j] != t->alt_volt[j]) + goto repeat; + return 0; + +repeat: + msleep(10); + } + + pr_err("pwr test: ERROR: AB8500 regulator %s ", s.name); + + if (t->mode != s.mode) + printk("mode is: %d expected: %d ", + s.mode, t->mode); + + if (t->hwmode != s.hwmode) + printk("hwmode is: %d expected: %d ", + s.hwmode, t->hwmode); + + if (t->volt_selected != s.volt_selected && + t->alt_volt_selected != s.volt_selected) { + printk("volt selected is: %d expected: %d ", + s.volt_selected, t->volt_selected); + if (t->alt_volt_selected) + printk("(alt volt: %d) ", t->alt_volt_selected); + } + + if (t->volt_len != s.volt_len) + printk("volt len is: %d expected: %d ", + s.volt_len, t->volt_len); + + for (j = 0; j < 4; j++) + if (s.hwmode_auto[j] != t->hwmode_auto[j]) + break; + if (j != 4 && s.hwmode != AB8500_HWMODE_NONE) { + + printk("hwmode auto:: {"); + for (j = 0; j < 4; j++) { + switch(s.hwmode_auto[j]) { + case HWM_OFF: { printk("OFF "); break; } + case HWM_ON: { printk("ON "); break; } + case HWM_INVAL: { printk("INVAL "); break; } + } + } + printk("}, expected: {"); + for (j = 0; j < 4; j++) { + switch(t->hwmode_auto[j]) { + case HWM_OFF: { printk("OFF "); break; } + case HWM_ON: { printk("ON "); break; } + case HWM_INVAL: { printk("INVAL "); break; } + } + } + printk("} "); + } + + if (s.volt_len == t->volt_len) { + for (j = 0; j < s.volt_len; j++) + if (s.volt[j] != t->volt[j] && + t->alt_volt[j] != s.volt[j]) + break; + + } else { + j = 0; + } + + if (j != s.volt_len) { + printk("voltage: {"); + for (j = 0; j < s.volt_len; j++) + printk("%d ", s.volt[j]); + + if (t->alt_volt) { + printk("} alt voltage: {"); + for (j = 0; j < s.volt_len; j++) + printk("%d ", t->alt_volt[j]); + } + printk("} expected: {"); + for (j = 0; j < t->volt_len; j++) + printk("%d ", t->volt[j]); + printk("} "); + } + + printk("\n"); + + return -EINVAL; +} + + +static int test_execute(struct pwr_test *t, int len) +{ + int err = 0; + int i; + + for (i = 0 ; i < len ; i++) { + switch (t[i].type) { + case CLK_ABB_SYS: + err |= clk_read_abb_sys(&t[i]); + break; + case CLK_PRCMU: + err |= clk_read_prcmu(&t[i]); + break; + case CLK_PAR_PRCMU: + err |= clk_read_par_prcmu(&t[i]); + break; + case RAW: + err |= read_raw(&t[i]); + break; + case REG_DB8500: + err |= reg_read_db8500(&t[i]); + break; + case REG_AB8500: + err |= reg_read_ab8500(&t[i]); + break; + default: + break; + } + + } + return err; +} + +static int pwr_test_idle(struct seq_file *s, void *data) +{ + int err; + + err = test_execute(idle_test, ARRAY_SIZE(idle_test)); + + seq_printf(s, "%s\n", err == 0 ? "PASS" : "FAIL"); + + return 0; +} + + +int dbx500_regulator_testcase(struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + u8500_reg.db8500_reg = regulator_info; + u8500_reg.db8500_num = num_regulators; + return 0; +} + +static int pwr_test_debugfs_open(struct inode *inode, + struct file *file) +{ + return single_open(file, + inode->i_private, + NULL); +} + +static const struct file_operations pwr_test_debugfs_ops = { + .open = pwr_test_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *debugfs_dir; + +static int __init pwr_test_init(void) +{ + int err = 0; + void *err_ptr; + + debugfs_dir = debugfs_create_dir("pwr_test", NULL); + if (IS_ERR(debugfs_dir)) + return PTR_ERR(debugfs_dir); + + err_ptr = debugfs_create_file("idle", + S_IFREG | S_IRUGO, + debugfs_dir, (void *)pwr_test_idle, + &pwr_test_debugfs_ops); + if (IS_ERR(err_ptr)) { + err = PTR_ERR(err_ptr); + goto out; + } + return 0; +out: + debugfs_remove_recursive(debugfs_dir); + return err; +} +late_initcall(pwr_test_init); diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index e69ca9b50a2..438c9715aab 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -7,6 +7,7 @@ #include <linux/io.h> #include <linux/errno.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/clksrc-db5500-mtimer.h> #include <linux/of.h> #include <asm/smp_twd.h> @@ -85,12 +86,18 @@ static void __init ux500_timer_init(void) * depending on delay which is not yet calibrated. RTC-RTT is in the * always-on powerdomain and is used as clockevent instead of twd when * sleeping. - * The PRCMU timer 4(3 for DB5500) register a clocksource and - * sched_clock with higher rating then MTU since is always-on. * + * The PRCMU timer 4 (3 for DB5500) registers a clocksource and + * sched_clock with higher rating than the MTU since it is + * always-on. + * + * On DB5500, the MTIMER is the best clocksource since, unlike the + * PRCMU timer, it doesn't occasionally go backwards. */ nmdk_timer_init(mtu_timer_base); + if (cpu_is_u5500()) + db5500_mtimer_init(__io_address(U5500_MTIMER_BASE)); clksrc_dbx500_prcmu_init(prcmu_timer_base); ux500_twd_init(); diff --git a/arch/arm/mach-ux500/uart-db8500.c b/arch/arm/mach-ux500/uart-db8500.c new file mode 100644 index 00000000000..fad9b9a13df --- /dev/null +++ b/arch/arm/mach-ux500/uart-db8500.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Arun R Murthy <arun.murthy@stericsson.com>, + * Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/amba/serial.h> +#include <mach/setup.h> +#include <mach/hardware.h> +#include <mach/context.h> + +#ifdef CONFIG_UX500_CONTEXT + +static struct { + struct clk *uart_clk; + void __iomem *base; + /* dr */ + /* rsr_err */ + u32 dma_wm; + u32 timeout; + /* fr */ + u32 lcrh_rx; + u32 ilpr; + u32 ibrd; + u32 fbrd; + u32 lcrh_tx; + u32 cr; + u32 ifls; + u32 imsc; + /* ris */ + /* mis */ + /* icr */ + u32 dmacr; + u32 xfcr; + u32 xon1; + u32 xon2; + u32 xoff1; + u32 xoff2; + /* itcr */ + /* itip */ + /* itop */ + /* tdr */ + u32 abcr; + /* absr */ + /* abfmt */ + /* abdr */ + /* abdfr */ + /* abmr */ + u32 abimsc; + /* abris */ + /* abmis */ + /* abicr */ + /* id_product_h_xy */ + /* id_provider */ + /* periphid0 */ + /* periphid1 */ + /* periphid2 */ + /* periphid3 */ + /* pcellid0 */ + /* pcellid1 */ + /* pcellid2 */ + /* pcellid3 */ +} context_uart; + +static void save_uart(void) +{ + void __iomem *membase; + + membase = context_uart.base; + + clk_enable(context_uart.uart_clk); + + context_uart.dma_wm = readl_relaxed(membase + ST_UART011_DMAWM); + context_uart.timeout = readl_relaxed(membase + ST_UART011_TIMEOUT); + context_uart.lcrh_rx = readl_relaxed(membase + ST_UART011_LCRH_RX); + context_uart.ilpr = readl_relaxed(membase + UART01x_ILPR); + context_uart.ibrd = readl_relaxed(membase + UART011_IBRD); + context_uart.fbrd = readl_relaxed(membase + UART011_FBRD); + context_uart.lcrh_tx = readl_relaxed(membase + ST_UART011_LCRH_TX); + context_uart.cr = readl_relaxed(membase + UART011_CR); + context_uart.ifls = readl_relaxed(membase + UART011_IFLS); + context_uart.imsc = readl_relaxed(membase + UART011_IMSC); + context_uart.dmacr = readl_relaxed(membase + UART011_DMACR); + context_uart.xfcr = readl_relaxed(membase + ST_UART011_XFCR); + context_uart.xon1 = readl_relaxed(membase + ST_UART011_XON1); + context_uart.xon2 = readl_relaxed(membase + ST_UART011_XON2); + context_uart.xoff1 = readl_relaxed(membase + ST_UART011_XOFF1); + context_uart.xoff2 = readl_relaxed(membase + ST_UART011_XOFF2); + context_uart.abcr = readl_relaxed(membase + ST_UART011_ABCR); + context_uart.abimsc = readl_relaxed(membase + ST_UART011_ABIMSC); + + clk_disable(context_uart.uart_clk); +} + +static void restore_uart(void) +{ + int cnt; + int retries = 100; + unsigned int cr; + void __iomem *membase; + u16 dummy; + bool show_warn = false; + + membase = context_uart.base; + clk_enable(context_uart.uart_clk); + + writew_relaxed(context_uart.ifls, membase + UART011_IFLS); + cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE; + + writew_relaxed(cr, membase + UART011_CR); + writew_relaxed(0, membase + UART011_FBRD); + writew_relaxed(1, membase + UART011_IBRD); + writew_relaxed(0, membase + ST_UART011_LCRH_RX); + if (context_uart.lcrh_tx != ST_UART011_LCRH_RX) { + int i; + /* + * Wait 10 PCLKs before writing LCRH_TX register, + * to get this delay write read only register 10 times + */ + for (i = 0; i < 10; ++i) + dummy = readw(membase + ST_UART011_LCRH_RX); + writew_relaxed(0, membase + ST_UART011_LCRH_TX); + } + writew(0, membase + UART01x_DR); + do { + if (!(readw(membase + UART01x_FR) & UART01x_FR_BUSY)) + break; + cpu_relax(); + } while (retries-- > 0); + if (retries < 0) + /* + * We can't print out a warning here since the uart is + * not fully restored. Do it later. + */ + show_warn = true; + + writel_relaxed(context_uart.dma_wm, membase + ST_UART011_DMAWM); + writel_relaxed(context_uart.timeout, membase + ST_UART011_TIMEOUT); + writel_relaxed(context_uart.lcrh_rx, membase + ST_UART011_LCRH_RX); + writel_relaxed(context_uart.ilpr, membase + UART01x_ILPR); + writel_relaxed(context_uart.ibrd, membase + UART011_IBRD); + writel_relaxed(context_uart.fbrd, membase + UART011_FBRD); + /* + * Wait 10 PCLKs before writing LCRH_TX register, + * to get this delay write read only register 10-3 + * times, as already there are 3 writes after + * ST_UART011_LCRH_RX + */ + for (cnt = 0; cnt < 7; cnt++) + dummy = readw(membase + ST_UART011_LCRH_RX); + + writel_relaxed(context_uart.lcrh_tx, membase + ST_UART011_LCRH_TX); + writel_relaxed(context_uart.ifls, membase + UART011_IFLS); + writel_relaxed(context_uart.dmacr, membase + UART011_DMACR); + writel_relaxed(context_uart.xfcr, membase + ST_UART011_XFCR); + writel_relaxed(context_uart.xon1, membase + ST_UART011_XON1); + writel_relaxed(context_uart.xon2, membase + ST_UART011_XON2); + writel_relaxed(context_uart.xoff1, membase + ST_UART011_XOFF1); + writel_relaxed(context_uart.xoff2, membase + ST_UART011_XOFF2); + writel_relaxed(context_uart.abcr, membase + ST_UART011_ABCR); + writel_relaxed(context_uart.abimsc, membase + ST_UART011_ABIMSC); + writel_relaxed(context_uart.cr, membase + UART011_CR); + writel(context_uart.imsc, membase + UART011_IMSC); + + clk_disable(context_uart.uart_clk); + + if (show_warn) + pr_warning("%s:uart tx busy\n", __func__); +} + +static int uart_context_notifier_call(struct notifier_block *this, + unsigned long event, void *data) +{ + switch (event) { + case CONTEXT_APE_SAVE: + save_uart(); + break; + + case CONTEXT_APE_RESTORE: + restore_uart(); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block uart_context_notifier = { + .notifier_call = uart_context_notifier_call, +}; + +#define __UART_BASE(soc, x) soc##_UART##x##_BASE +#define UART_BASE(soc, x) __UART_BASE(soc, x) + +static int __init uart_context_notifier_init(void) +{ + unsigned long base; + static const char clkname[] __initconst + = "uart" __stringify(CONFIG_UX500_DEBUG_UART); + + if (cpu_is_u8500()) + base = UART_BASE(U8500, CONFIG_UX500_DEBUG_UART); + else if (cpu_is_u5500()) + base = UART_BASE(U5500, CONFIG_UX500_DEBUG_UART); + else + ux500_unknown_soc(); + + context_uart.base = ioremap(base, SZ_4K); + context_uart.uart_clk = clk_get_sys(clkname, NULL); + + if (IS_ERR(context_uart.uart_clk)) { + pr_err("%s:unable to get clk-uart%d\n", __func__, + CONFIG_UX500_DEBUG_UART); + return -EINVAL; + } + + return WARN_ON(context_ape_notifier_register(&uart_context_notifier)); +} +arch_initcall(uart_context_notifier_init); +#endif diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S index 07201637109..226f8736152 100644 --- a/arch/arm/mm/cache-fa.S +++ b/arch/arm/mm/cache-fa.S @@ -240,6 +240,24 @@ ENTRY(fa_dma_unmap_area) mov pc, lr ENDPROC(fa_dma_unmap_area) +/* + * clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(fa_clean_dcache_all) + mov pc, lr +ENDPROC(fa_clean_dcache_all) + +/* + * flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(fa_flush_dcache_all) + mov pc, lr +ENDPROC(fa_flush_dcache_all) + __INITDATA @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 2a8e380501e..1768e4038fc 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -319,9 +319,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); - aux &= aux_mask; - aux |= aux_val; - /* Determine the number of ways */ switch (cache_id & L2X0_CACHE_ID_PART_MASK) { case L2X0_CACHE_ID_PART_L310: @@ -335,6 +332,13 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) sync_reg_offset = L2X0_DUMMY_REG; #endif outer_cache.set_debug = pl310_set_debug; + + /* + * Set bit 22 in the auxiliary control register. If this bit + * is cleared, PL310 treats Normal Shared Non-cacheable + * accesses as Cacheable no-allocate. + */ + aux_val |= 1 << 22; break; case L2X0_CACHE_ID_PART_L210: ways = (aux >> 13) & 0xf; @@ -362,6 +366,9 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) * accessing the below registers will fault. */ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + aux &= aux_mask; + aux |= aux_val; + /* Make sure that I&D is not locked down when starting */ l2x0_unlock(cache_id); diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S index c2301f22610..ab5bf508a2a 100644 --- a/arch/arm/mm/cache-v3.S +++ b/arch/arm/mm/cache-v3.S @@ -127,6 +127,24 @@ ENTRY(v3_dma_map_area) ENDPROC(v3_dma_unmap_area) ENDPROC(v3_dma_map_area) +/* + * clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(v3_clean_dcache_all) + mov pc, lr +ENDPROC(v3_clean_dcache_all) + +/* + * flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(v3_flush_dcache_all) + mov pc, lr +ENDPROC(v3_flush_dcache_all) + __INITDATA @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index fd9bb7addc8..9d3a055127e 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -139,6 +139,24 @@ ENTRY(v4_dma_map_area) ENDPROC(v4_dma_unmap_area) ENDPROC(v4_dma_map_area) +/* + * clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(v4_clean_dcache_all) + mov pc, lr +ENDPROC(v4_clean_dcache_all) + +/* + * flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(v4_flush_dcache_all) + mov pc, lr +ENDPROC(v4_flush_dcache_all) + __INITDATA @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 4f2c14151cc..54d3cda4a89 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -251,6 +251,24 @@ ENTRY(v4wb_dma_unmap_area) mov pc, lr ENDPROC(v4wb_dma_unmap_area) +/* + * clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(v4wb_clean_dcache_all) + mov pc, lr +ENDPROC(v4wb_clean_dcache_all) + +/* + * flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(v4wb_flush_dcache_all) + mov pc, lr +ENDPROC(v4wb_flush_dcache_all) + __INITDATA @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S index 4d7b467631c..40f7dba11f5 100644 --- a/arch/arm/mm/cache-v4wt.S +++ b/arch/arm/mm/cache-v4wt.S @@ -195,6 +195,24 @@ ENTRY(v4wt_dma_map_area) ENDPROC(v4wt_dma_unmap_area) ENDPROC(v4wt_dma_map_area) +/* + * clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(v4wt_clean_dcache_all) + mov pc, lr +ENDPROC(v4wt_clean_dcache_all) + +/* + * flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(v4wt_flush_dcache_all) + mov pc, lr +ENDPROC(v4wt_flush_dcache_all) + __INITDATA @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 74c2e5a33a4..b88dd4ab038 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -328,6 +328,24 @@ ENTRY(v6_dma_unmap_area) mov pc, lr ENDPROC(v6_dma_unmap_area) +/* + * clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(v6_clean_dcache_all) + mov pc, lr +ENDPROC(v6_clean_dcache_all) + +/* + * flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(v6_flush_dcache_all) + mov pc, lr +ENDPROC(v6_flush_dcache_all) + __INITDATA @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index a655d3da386..70744d6a066 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -33,7 +33,7 @@ ENTRY(v7_flush_icache_all) ENDPROC(v7_flush_icache_all) /* - * v7_flush_dcache_all() + * __v7_flush_dcache_all() * * Flush the whole D-cache. * @@ -41,7 +41,7 @@ ENDPROC(v7_flush_icache_all) * * - mm - mm_struct describing address space */ -ENTRY(v7_flush_dcache_all) +ENTRY(__v7_flush_dcache_all) dmb @ ensure ordering with previous memory accesses mrc p15, 1, r0, c0, c0, 1 @ read clidr ands r3, r0, #0x7000000 @ extract loc from clidr @@ -94,9 +94,93 @@ finished: dsb isb mov pc, lr +ENDPROC(__v7_flush_dcache_all) + +/* + * __v7_clean_dcache_all() + * + * Clean the whole D-cache. + * + * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) + */ +ENTRY(__v7_clean_dcache_all) + dmb @ ensure ordering with previous memory accesses + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished1 @ if loc is 0, then no need to clean + mov r10, #0 @ start clean at cache level 0 +loop21: + add r2, r10, r10, lsr #1 @ work out 3x current cache level + mov r1, r0, lsr r2 @ extract cache type bits from clidr + and r1, r1, #7 @ mask of the bits for current cache only + cmp r1, #2 @ see what cache we have at this level + blt skip1 @ skip if no cache, or just i-cache + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + isb @ isb to sych the new cssr&csidr + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + and r2, r1, #7 @ extract the length of the cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the way size + clz r5, r4 @ find bit position of way size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the index size +loop22: + mov r9, r4 @ create working copy of max way size +loop23: + ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11 + THUMB( lsl r6, r9, r5 ) + THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 + ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11 + THUMB( lsl r6, r7, r2 ) + THUMB( orr r11, r11, r6 ) @ factor index number into r11 + mcr p15, 0, r11, c7, c10, 2 @ clean by set/way + subs r9, r9, #1 @ decrement the way + bge loop23 + subs r7, r7, #1 @ decrement the index + bge loop22 +skip1: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt loop21 +finished1: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + dsb + isb + mov pc, lr +ENDPROC(__v7_clean_dcache_all) + +/* + * v7_flush_dcache_all() + * + * Flush the whole D-cache. + */ +ENTRY(v7_flush_dcache_all) + ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) + THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) + bl __v7_flush_dcache_all + ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) + THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) + mov pc, lr ENDPROC(v7_flush_dcache_all) /* + * v7_clean_dcache_all() + * + * Clean the whole D-cache. + */ +ENTRY(v7_clean_dcache_all) + ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) + THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) + bl __v7_clean_dcache_all + ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) + THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) + mov pc, lr +ENDPROC(v7_clean_dcache_all) + +/* * v7_flush_cache_all() * * Flush the entire cache system. @@ -108,14 +192,12 @@ ENDPROC(v7_flush_dcache_all) * */ ENTRY(v7_flush_kern_cache_all) - ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) - THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) + stmfd sp!, {lr} bl v7_flush_dcache_all mov r0, #0 ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate - ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) - THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) + ldmfd sp!, {lr} mov pc, lr ENDPROC(v7_flush_kern_cache_all) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index aa78de8bfdd..4ecd1f8bbb5 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -288,6 +288,20 @@ static struct mem_type mem_types[] = { PMD_SECT_UNCACHED | PMD_SECT_XN, .domain = DOMAIN_KERNEL, }, + /* NOTE : this is only a temporary hack!!! + * The U8500 ED/V1.0 cuts require such a + * memory type for deep sleep resume. + * This is expected to be solved in cut v2.0 + * and we clean this up then. for more details + * look @ the commit message please + */ + [MT_BACKUP_RAM] = { + .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED | + L_PTE_SHARED, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S, + .domain = DOMAIN_IO, + }, }; const struct mem_type *get_mem_type(unsigned int type) diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 2d8ff3ad86d..518ab10fea5 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -304,6 +304,8 @@ ENTRY(\name\()_cache_fns) .long \name\()_coherent_kern_range .long \name\()_coherent_user_range .long \name\()_flush_kern_dcache_area + .long \name\()_clean_dcache_all + .long \name\()_flush_dcache_all .long \name\()_dma_map_area .long \name\()_dma_unmap_area .long \name\()_dma_flush_range diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index c2e2b66f72b..d1c42ead765 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -172,7 +172,7 @@ __v7_ca15mp_setup: __v7_setup: adr r12, __v7_setup_stack @ the local stack stmia r12, {r0-r5, r7, r9, r11, lr} - bl v7_flush_dcache_all + bl __v7_flush_dcache_all ldmia r12, {r0-r5, r7, r9, r11, lr} mrc p15, 0, r0, c0, c0, 0 @ read main ID register diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h index 582641f3dc0..489e92723b4 100644 --- a/arch/arm/plat-nomadik/include/plat/mtu.h +++ b/arch/arm/plat-nomadik/include/plat/mtu.h @@ -5,5 +5,7 @@ void nmdk_timer_init(void __iomem *base); void nmdk_clkevt_reset(void); void nmdk_clksrc_reset(void); +struct clock_event_device *nmdk_clkevt_get(void); + #endif /* __PLAT_MTU_H */ diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index f9c9f33f8cb..bb2f9e9d6d2 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,531 +12,3179 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# This is a cut-down version of the file; it contains only machines that -# are merged into mainline or have been edited in the machine database -# within the last 12 months. References to machine_is_NAME() do not count! -# -# Last update: Tue Dec 6 11:07:38 2011 +# Last update: Thu Feb 2 12:49:17 2012 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # ebsa110 ARCH_EBSA110 EBSA110 0 riscpc ARCH_RPC RISCPC 1 +nexuspci ARCH_NEXUSPCI NEXUSPCI 3 ebsa285 ARCH_EBSA285 EBSA285 4 netwinder ARCH_NETWINDER NETWINDER 5 cats ARCH_CATS CATS 6 +tbox ARCH_TBOX TBOX 7 +co285 ARCH_CO285 CO285 8 +clps7110 ARCH_CLPS7110 CLPS7110 9 +archimedes ARCH_ARC ARCHIMEDES 10 +a5k ARCH_A5K A5K 11 +etoile ARCH_ETOILE ETOILE 12 +lacie_nas ARCH_LACIE_NAS LACIE_NAS 13 +clps7500 ARCH_CLPS7500 CLPS7500 14 shark ARCH_SHARK SHARK 15 brutus SA1100_BRUTUS BRUTUS 16 personal_server ARCH_PERSONAL_SERVER PERSONAL_SERVER 17 +itsy SA1100_ITSY ITSY 18 l7200 ARCH_L7200 L7200 19 pleb SA1100_PLEB PLEB 20 integrator ARCH_INTEGRATOR INTEGRATOR 21 h3600 SA1100_H3600 H3600 22 +ixp1200 ARCH_IXP1200 IXP1200 23 p720t ARCH_P720T P720T 24 assabet SA1100_ASSABET ASSABET 25 +victor SA1100_VICTOR VICTOR 26 lart SA1100_LART LART 27 +ranger SA1100_RANGER RANGER 28 graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29 xp860 SA1100_XP860 XP860 30 cerf SA1100_CERF CERF 31 nanoengine SA1100_NANOENGINE NANOENGINE 32 +fpic SA1100_FPIC FPIC 33 +extenex1 SA1100_EXTENEX1 EXTENEX1 34 +sherman SA1100_SHERMAN SHERMAN 35 +accelent_sa SA1100_ACCELENT ACCELENT_SA 36 +accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37 +netport SA1100_NETPORT NETPORT 38 +pangolin SA1100_PANGOLIN PANGOLIN 39 +yopy SA1100_YOPY YOPY 40 +coolidge SA1100_COOLIDGE COOLIDGE 41 +huw_webpanel SA1100_HUW_WEBPANEL HUW_WEBPANEL 42 +spotme ARCH_SPOTME SPOTME 43 +freebird ARCH_FREEBIRD FREEBIRD 44 +ti925 ARCH_TI925 TI925 45 +riscstation ARCH_RISCSTATION RISCSTATION 46 +cavy SA1100_CAVY CAVY 47 jornada720 SA1100_JORNADA720 JORNADA720 48 +omnimeter SA1100_OMNIMETER OMNIMETER 49 edb7211 ARCH_EDB7211 EDB7211 50 +citygo SA1100_CITYGO CITYGO 51 pfs168 SA1100_PFS168 PFS168 52 +spot SA1100_SPOT SPOT 53 flexanet SA1100_FLEXANET FLEXANET 54 +webpal ARCH_WEBPAL WEBPAL 55 +linpda SA1100_LINPDA LINPDA 56 +anakin ARCH_ANAKIN ANAKIN 57 +mvi SA1100_MVI MVI 58 +jupiter SA1100_JUPITER JUPITER 59 +psionw ARCH_PSIONW PSIONW 60 +aln SA1100_ALN ALN 61 +epxa ARCH_CAMELOT CAMELOT 62 +gds2200 SA1100_GDS2200 GDS2200 63 +netbook SA1100_PSION_SERIES7 PSION_SERIES7 64 +xfile SA1100_XFILE XFILE 65 +accelent_ep9312 ARCH_ACCELENT_EP9312 ACCELENT_EP9312 66 +ic200 ARCH_IC200 IC200 67 +creditlart SA1100_CREDITLART CREDITLART 68 +htm SA1100_HTM HTM 69 +iq80310 ARCH_IQ80310 IQ80310 70 +freebot SA1100_FREEBOT FREEBOT 71 +entel ARCH_ENTEL ENTEL 72 +enp3510 ARCH_ENP3510 ENP3510 73 +trizeps SA1100_TRIZEPS TRIZEPS 74 +nesa SA1100_NESA NESA 75 +venus ARCH_VENUS VENUS 76 +tardis ARCH_TARDIS TARDIS 77 +mercury ARCH_MERCURY MERCURY 78 +empeg SA1100_EMPEG EMPEG 79 +adi_evb ARCH_I80200FCC I80200FCC 80 +itt_cpb SA1100_ITT_CPB ITT_CPB 81 +svc SA1100_SVC SVC 82 +alpha2 SA1100_ALPHA2 ALPHA2 84 +alpha1 SA1100_ALPHA1 ALPHA1 85 +netarm ARCH_NETARM NETARM 86 simpad SA1100_SIMPAD SIMPAD 87 +pda1 ARCH_PDA1 PDA1 88 lubbock ARCH_LUBBOCK LUBBOCK 89 +aniko ARCH_ANIKO ANIKO 90 clep7212 ARCH_CLEP7212 CLEP7212 91 +cs89712 ARCH_CS89712 CS89712 92 +weararm SA1100_WEARARM WEARARM 93 +possio_px SA1100_POSSIO_PX POSSIO_PX 94 +sidearm SA1100_SIDEARM SIDEARM 95 +stork SA1100_STORK STORK 96 shannon SA1100_SHANNON SHANNON 97 +ace ARCH_ACE ACE 98 +ballyarm SA1100_BALLYARM BALLYARM 99 +simputer SA1100_SIMPUTER SIMPUTER 100 +nexterm SA1100_NEXTERM NEXTERM 101 +sa1100_elf SA1100_SA1100_ELF SA1100_ELF 102 +gator SA1100_GATOR GATOR 103 +granite ARCH_GRANITE GRANITE 104 consus SA1100_CONSUS CONSUS 105 aaed2000 ARCH_AAED2000 AAED2000 106 cdb89712 ARCH_CDB89712 CDB89712 107 graphicsmaster SA1100_GRAPHICSMASTER GRAPHICSMASTER 108 adsbitsy SA1100_ADSBITSY ADSBITSY 109 pxa_idp ARCH_PXA_IDP PXA_IDP 110 +plce ARCH_PLCE PLCE 111 pt_system3 SA1100_PT_SYSTEM3 PT_SYSTEM3 112 +murphy ARCH_MEDALB MEDALB 113 +eagle ARCH_EAGLE EAGLE 114 +dsc21 ARCH_DSC21 DSC21 115 +dsc24 ARCH_DSC24 DSC24 116 +ti5472 ARCH_TI5472 TI5472 117 autcpu12 ARCH_AUTCPU12 AUTCPU12 118 +uengine ARCH_UENGINE UENGINE 119 +bluestem SA1100_BLUESTEM BLUESTEM 120 +xingu8 ARCH_XINGU8 XINGU8 121 +bushstb ARCH_BUSHSTB BUSHSTB 122 +epsilon1 SA1100_EPSILON1 EPSILON1 123 +balloon SA1100_BALLOON BALLOON 124 +puppy ARCH_PUPPY PUPPY 125 +elroy SA1100_ELROY ELROY 126 +gms720 ARCH_GMS720 GMS720 127 +s24x ARCH_S24X S24X 128 +jtel_clep7312 ARCH_JTEL_CLEP7312 JTEL_CLEP7312 129 +cx821xx ARCH_CX821XX CX821XX 130 +edb7312 ARCH_EDB7312 EDB7312 131 +bsa1110 SA1100_BSA1110 BSA1110 132 +powerpin ARCH_POWERPIN POWERPIN 133 +openarm ARCH_OPENARM OPENARM 134 +whitechapel SA1100_WHITECHAPEL WHITECHAPEL 135 h3100 SA1100_H3100 H3100 136 +h3800 SA1100_H3800 H3800 137 +blue_v1 ARCH_BLUE_V1 BLUE_V1 138 +pxa_cerf ARCH_PXA_CERF PXA_CERF 139 +arm7tevb ARCH_ARM7TEVB ARM7TEVB 140 +d7400 SA1100_D7400 D7400 141 +piranha ARCH_PIRANHA PIRANHA 142 +sbcamelot SA1100_SBCAMELOT SBCAMELOT 143 +kings SA1100_KINGS KINGS 144 +smdk2400 ARCH_SMDK2400 SMDK2400 145 collie SA1100_COLLIE COLLIE 146 +idr ARCH_IDR IDR 147 badge4 SA1100_BADGE4 BADGE4 148 +webnet ARCH_WEBNET WEBNET 149 +d7300 SA1100_D7300 D7300 150 +cep SA1100_CEP CEP 151 fortunet ARCH_FORTUNET FORTUNET 152 +vc547x ARCH_VC547X VC547X 153 +filewalker SA1100_FILEWALKER FILEWALKER 154 +netgateway SA1100_NETGATEWAY NETGATEWAY 155 +symbol2800 SA1100_SYMBOL2800 SYMBOL2800 156 +suns SA1100_SUNS SUNS 157 +frodo SA1100_FRODO FRODO 158 +ms301 SA1100_MACH_TYTE_MS301 MACH_TYTE_MS301 159 mx1ads ARCH_MX1ADS MX1ADS 160 h7201 ARCH_H7201 H7201 161 h7202 ARCH_H7202 H7202 162 +amico ARCH_AMICO AMICO 163 +iam SA1100_IAM IAM 164 +tt530 SA1100_TT530 TT530 165 +sam2400 ARCH_SAM2400 SAM2400 166 +jornada56x SA1100_JORNADA56X JORNADA56X 167 +active SA1100_ACTIVE ACTIVE 168 iq80321 ARCH_IQ80321 IQ80321 169 +wid SA1100_WID WID 170 +sabinal ARCH_SABINAL SABINAL 171 +ixp425_matacumbe ARCH_IXP425_MATACUMBE IXP425_MATACUMBE 172 +miniprint SA1100_MINIPRINT MINIPRINT 173 +adm510x ARCH_ADM510X ADM510X 174 +svs200 SA1100_SVS200 SVS200 175 +atg_tcu ARCH_ATG_TCU ATG_TCU 176 +jornada820 SA1100_JORNADA820 JORNADA820 177 +s3c44b0 ARCH_S3C44B0 S3C44B0 178 +margis2 ARCH_MARGIS2 MARGIS2 179 ks8695 ARCH_KS8695 KS8695 180 +brh ARCH_BRH BRH 181 +s3c2410 ARCH_S3C2410 S3C2410 182 +possio_px30 ARCH_POSSIO_PX30 POSSIO_PX30 183 +s3c2800 ARCH_S3C2800 S3C2800 184 +fleetwood SA1100_FLEETWOOD FLEETWOOD 185 +omaha ARCH_OMAHA OMAHA 186 +ta7 ARCH_TA7 TA7 187 +nova SA1100_NOVA NOVA 188 +hmk ARCH_HMK HMK 189 karo ARCH_KARO KARO 190 +fester SA1100_FESTER FESTER 191 +gpi ARCH_GPI GPI 192 smdk2410 ARCH_SMDK2410 SMDK2410 193 +i519 ARCH_I519 I519 194 +nexio SA1100_NEXIO NEXIO 195 +bitbox SA1100_BITBOX BITBOX 196 +g200 SA1100_G200 G200 197 +gill SA1100_GILL GILL 198 +pxa_mercury ARCH_PXA_MERCURY PXA_MERCURY 199 ceiva ARCH_CEIVA CEIVA 200 +fret SA1100_FRET FRET 201 +emailphone SA1100_EMAILPHONE EMAILPHONE 202 +h3900 ARCH_H3900 H3900 203 +pxa1 ARCH_PXA1 PXA1 204 +koan369 SA1100_KOAN369 KOAN369 205 +cogent ARCH_COGENT COGENT 206 +esl_simputer ARCH_ESL_SIMPUTER ESL_SIMPUTER 207 +esl_simputer_clr ARCH_ESL_SIMPUTER_CLR ESL_SIMPUTER_CLR 208 +esl_simputer_bw ARCH_ESL_SIMPUTER_BW ESL_SIMPUTER_BW 209 +hhp_cradle ARCH_HHP_CRADLE HHP_CRADLE 210 +he500 ARCH_HE500 HE500 211 +inhandelf2 SA1100_INHANDELF2 INHANDELF2 212 +inhandftip SA1100_INHANDFTIP INHANDFTIP 213 +dnp1110 SA1100_DNP1110 DNP1110 214 +pnp1110 SA1100_PNP1110 PNP1110 215 +csb226 ARCH_CSB226 CSB226 216 +arnold SA1100_ARNOLD ARNOLD 217 voiceblue MACH_VOICEBLUE VOICEBLUE 218 +jz8028 ARCH_JZ8028 JZ8028 219 h5400 ARCH_H5400 H5400 220 +forte SA1100_FORTE FORTE 221 +acam SA1100_ACAM ACAM 222 +abox SA1100_ABOX ABOX 223 +atmel ARCH_ATMEL ATMEL 224 +sitsang ARCH_SITSANG SITSANG 225 +cpu1110lcdnet SA1100_CPU1110LCDNET CPU1110LCDNET 226 +mpl_vcma9 ARCH_MPL_VCMA9 MPL_VCMA9 227 +opus_a1 ARCH_OPUS_A1 OPUS_A1 228 +daytona ARCH_DAYTONA DAYTONA 229 +killbear SA1100_KILLBEAR KILLBEAR 230 +yoho ARCH_YOHO YOHO 231 +jasper ARCH_JASPER JASPER 232 +dsc25 ARCH_DSC25 DSC25 233 omap_innovator MACH_OMAP_INNOVATOR OMAP_INNOVATOR 234 +mnci ARCH_RAMSES RAMSES 235 +s28x ARCH_S28X S28X 236 +mport3 ARCH_MPORT3 MPORT3 237 +pxa_eagle250 ARCH_PXA_EAGLE250 PXA_EAGLE250 238 +pdb ARCH_PDB PDB 239 +blue_2g SA1100_BLUE_2G BLUE_2G 240 +bluearch SA1100_BLUEARCH BLUEARCH 241 ixdp2400 ARCH_IXDP2400 IXDP2400 242 ixdp2800 ARCH_IXDP2800 IXDP2800 243 +explorer SA1100_EXPLORER EXPLORER 244 ixdp425 ARCH_IXDP425 IXDP425 245 +chimp ARCH_CHIMP CHIMP 246 +stork_nest ARCH_STORK_NEST STORK_NEST 247 +stork_egg ARCH_STORK_EGG STORK_EGG 248 +wismo SA1100_WISMO WISMO 249 +ezlinx ARCH_EZLINX EZLINX 250 +at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 +adtech_orion ARCH_ADTECH_ORION ADTECH_ORION 252 +neptune ARCH_NEPTUNE NEPTUNE 253 hackkit SA1100_HACKKIT HACKKIT 254 +pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 +lavinna SA1100_LAVINNA LAVINNA 256 +pxa_uengine ARCH_PXA_UENGINE PXA_UENGINE 257 +innokom ARCH_INNOKOM INNOKOM 258 +bms ARCH_BMS BMS 259 ixcdp1100 ARCH_IXCDP1100 IXCDP1100 260 +prpmc1100 ARCH_PRPMC1100 PRPMC1100 261 at91rm9200dk ARCH_AT91RM9200DK AT91RM9200DK 262 +armstick ARCH_ARMSTICK ARMSTICK 263 +armonie ARCH_ARMONIE ARMONIE 264 +mport1 ARCH_MPORT1 MPORT1 265 +s3c5410 ARCH_S3C5410 S3C5410 266 +zcp320a ARCH_ZCP320A ZCP320A 267 +i_box ARCH_I_BOX I_BOX 268 +stlc1502 ARCH_STLC1502 STLC1502 269 +siren ARCH_SIREN SIREN 270 +greenlake ARCH_GREENLAKE GREENLAKE 271 +argus ARCH_ARGUS ARGUS 272 +combadge SA1100_COMBADGE COMBADGE 273 +rokepxa ARCH_ROKEPXA ROKEPXA 274 cintegrator ARCH_CINTEGRATOR CINTEGRATOR 275 +guidea07 ARCH_GUIDEA07 GUIDEA07 276 +tat257 ARCH_TAT257 TAT257 277 +igp2425 ARCH_IGP2425 IGP2425 278 +bluegrama ARCH_BLUEGRAMMA BLUEGRAMMA 279 +ipod ARCH_IPOD IPOD 280 +adsbitsyx ARCH_ADSBITSYX ADSBITSYX 281 +trizeps2 ARCH_TRIZEPS2 TRIZEPS2 282 viper ARCH_VIPER VIPER 283 +adsbitsyplus SA1100_ADSBITSYPLUS ADSBITSYPLUS 284 +adsagc SA1100_ADSAGC ADSAGC 285 +stp7312 ARCH_STP7312 STP7312 286 +nx_phnx MACH_NX_PHNX NX_PHNX 287 +wep_ep250 ARCH_WEP_EP250 WEP_EP250 288 +inhandelf3 ARCH_INHANDELF3 INHANDELF3 289 adi_coyote ARCH_ADI_COYOTE ADI_COYOTE 290 +iyonix ARCH_IYONIX IYONIX 291 +damicam1 ARCH_DAMICAM_SA1110 DAMICAM_SA1110 292 +meg03 ARCH_MEG03 MEG03 293 +pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294 +nwsc ARCH_NWSC NWSC 295 +nwlarm ARCH_NWLARM NWLARM 296 +ixp425_mguard ARCH_IXP425_MGUARD IXP425_MGUARD 297 +pxa_netdcu4 ARCH_PXA_NETDCU4 PXA_NETDCU4 298 ixdp2401 ARCH_IXDP2401 IXDP2401 299 ixdp2801 ARCH_IXDP2801 IXDP2801 300 +zodiac ARCH_ZODIAC ZODIAC 301 +armmodul ARCH_ARMMODUL ARMMODUL 302 +ketop SA1100_KETOP KETOP 303 +av7200 ARCH_AV7200 AV7200 304 +arch_ti925 ARCH_ARCH_TI925 ARCH_TI925 305 +acq200 ARCH_ACQ200 ACQ200 306 +pt_dafit SA1100_PT_DAFIT PT_DAFIT 307 +ihba ARCH_IHBA IHBA 308 +quinque ARCH_QUINQUE QUINQUE 309 +nimbraone ARCH_NIMBRAONE NIMBRAONE 310 +nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 +nimbra210 ARCH_NIMBRA210 NIMBRA210 312 +hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 +labarm ARCH_LABARM LABARM 314 +m825xx ARCH_M825XX M825XX 315 +m7100 SA1100_M7100 M7100 316 +nipc2 ARCH_NIPC2 NIPC2 317 +fu7202 ARCH_FU7202 FU7202 318 +adsagx ARCH_ADSAGX ADSAGX 319 +pxa_pooh ARCH_PXA_POOH PXA_POOH 320 +bandon ARCH_BANDON BANDON 321 +pcm7210 ARCH_PCM7210 PCM7210 322 +nms9200 ARCH_NMS9200 NMS9200 323 +logodl ARCH_LOGODL LOGODL 324 +m7140 SA1100_M7140 M7140 325 +korebot ARCH_KOREBOT KOREBOT 326 iq31244 ARCH_IQ31244 IQ31244 327 +koan393 SA1100_KOAN393 KOAN393 328 +inhandftip3 ARCH_INHANDFTIP3 INHANDFTIP3 329 +gonzo ARCH_GONZO GONZO 330 bast ARCH_BAST BAST 331 +scanpass ARCH_SCANPASS SCANPASS 332 +ep7312_pooh ARCH_EP7312_POOH EP7312_POOH 333 +ta7s ARCH_TA7S TA7S 334 +ta7v ARCH_TA7V TA7V 335 +icarus SA1100_ICARUS ICARUS 336 +h1900 ARCH_H1900 H1900 337 +gemini SA1100_GEMINI GEMINI 338 +axim ARCH_AXIM AXIM 339 +audiotron ARCH_AUDIOTRON AUDIOTRON 340 +h2200 ARCH_H2200 H2200 341 +loox600 ARCH_LOOX600 LOOX600 342 +niop ARCH_NIOP NIOP 343 +dm310 ARCH_DM310 DM310 344 +seedpxa_c2 ARCH_SEEDPXA_C2 SEEDPXA_C2 345 +ixp4xx_mguardpci ARCH_IXP4XX_MGUARD_PCI IXP4XX_MGUARD_PCI 346 h1940 ARCH_H1940 H1940 347 +scorpio ARCH_SCORPIO SCORPIO 348 +viva ARCH_VIVA VIVA 349 +pxa_xcard ARCH_PXA_XCARD PXA_XCARD 350 +csb335 ARCH_CSB335 CSB335 351 +ixrd425 ARCH_IXRD425 IXRD425 352 +iq80315 ARCH_IQ80315 IQ80315 353 +nmp7312 ARCH_NMP7312 NMP7312 354 +cx861xx ARCH_CX861XX CX861XX 355 enp2611 ARCH_ENP2611 ENP2611 356 +xda SA1100_XDA XDA 357 +csir_ims ARCH_CSIR_IMS CSIR_IMS 358 +ixp421_dnaeeth ARCH_IXP421_DNAEETH IXP421_DNAEETH 359 +pocketserv9200 ARCH_POCKETSERV9200 POCKETSERV9200 360 +toto ARCH_TOTO TOTO 361 s3c2440 ARCH_S3C2440 S3C2440 362 +ks8695p ARCH_KS8695P KS8695P 363 +se4000 ARCH_SE4000 SE4000 364 +quadriceps ARCH_QUADRICEPS QUADRICEPS 365 +bronco ARCH_BRONCO BRONCO 366 +esl_wireless_tab ARCH_ESL_WIRELESS_TAB ESL_WIRELESS_TAB 367 +esl_sofcomp ARCH_ESL_SOFCOMP ESL_SOFCOMP 368 +s5c7375 ARCH_S5C7375 S5C7375 369 +spearhead ARCH_SPEARHEAD SPEARHEAD 370 +pantera ARCH_PANTERA PANTERA 371 +prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372 gumstix ARCH_GUMSTIX GUMSTIX 373 +rcube ARCH_RCUBE RCUBE 374 +rea_olv ARCH_REA_OLV REA_OLV 375 +pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376 +s3c3410 ARCH_S3C3410 S3C3410 377 +espd_4510b ARCH_ESPD_4510B ESPD_4510B 378 +mp1x ARCH_MP1X MP1X 379 +at91rm9200tb ARCH_AT91RM9200TB AT91RM9200TB 380 +adsvgx ARCH_ADSVGX ADSVGX 381 omap_h2 MACH_OMAP_H2 OMAP_H2 382 +pelee ARCH_PELEE PELEE 383 e740 MACH_E740 E740 384 iq80331 ARCH_IQ80331 IQ80331 385 versatile_pb ARCH_VERSATILE_PB VERSATILE_PB 387 kev7a400 MACH_KEV7A400 KEV7A400 388 lpd7a400 MACH_LPD7A400 LPD7A400 389 lpd7a404 MACH_LPD7A404 LPD7A404 390 +fujitsu_camelot ARCH_FUJITSU_CAMELOT FUJITSU_CAMELOT 391 +janus2m ARCH_JANUS2M JANUS2M 392 +embtf MACH_EMBTF EMBTF 393 +hpm MACH_HPM HPM 394 +smdk2410tk MACH_SMDK2410TK SMDK2410TK 395 +smdk2410aj MACH_SMDK2410AJ SMDK2410AJ 396 +streetracer MACH_STREETRACER STREETRACER 397 +eframe MACH_EFRAME EFRAME 398 csb337 MACH_CSB337 CSB337 399 +pxa_lark MACH_PXA_LARK PXA_LARK 400 +pxa_pnp2110 MACH_PNP2110 PNP2110 401 +tcc72x MACH_TCC72X TCC72X 402 +altair MACH_ALTAIR ALTAIR 403 +kc3 MACH_KC3 KC3 404 +sinteftd MACH_SINTEFTD SINTEFTD 405 mainstone MACH_MAINSTONE MAINSTONE 406 +aday4x MACH_ADAY4X ADAY4X 407 +lite300 MACH_LITE300 LITE300 408 +s5c7376 MACH_S5C7376 S5C7376 409 +mt02 MACH_MT02 MT02 410 +mport3s MACH_MPORT3S MPORT3S 411 +ra_alpha MACH_RA_ALPHA RA_ALPHA 412 xcep MACH_XCEP XCEP 413 arcom_vulcan MACH_ARCOM_VULCAN ARCOM_VULCAN 414 +stargate MACH_STARGATE STARGATE 415 +armadilloj MACH_ARMADILLOJ ARMADILLOJ 416 +elroy_jack MACH_ELROY_JACK ELROY_JACK 417 +backend MACH_BACKEND BACKEND 418 +s5linbox MACH_S5LINBOX S5LINBOX 419 nomadik MACH_NOMADIK NOMADIK 420 +ia_cpu_9200 MACH_IA_CPU_9200 IA_CPU_9200 421 +at91_bja1 MACH_AT91_BJA1 AT91_BJA1 422 corgi MACH_CORGI CORGI 423 poodle MACH_POODLE POODLE 424 +ten MACH_TEN TEN 425 +roverp5p MACH_ROVERP5P ROVERP5P 426 +sc2700 MACH_SC2700 SC2700 427 +ex_eagle MACH_EX_EAGLE EX_EAGLE 428 +nx_pxa12 MACH_NX_PXA12 NX_PXA12 429 +nx_pxa5 MACH_NX_PXA5 NX_PXA5 430 +blackboard2 MACH_BLACKBOARD2 BLACKBOARD2 431 +i819 MACH_I819 I819 432 +ixmb995e MACH_IXMB995E IXMB995E 433 +skyrider MACH_SKYRIDER SKYRIDER 434 +skyhawk MACH_SKYHAWK SKYHAWK 435 +enterprise MACH_ENTERPRISE ENTERPRISE 436 +dep2410 MACH_DEP2410 DEP2410 437 armcore MACH_ARMCORE ARMCORE 438 +hobbit MACH_HOBBIT HOBBIT 439 +h7210 MACH_H7210 H7210 440 +pxa_netdcu5 MACH_PXA_NETDCU5 PXA_NETDCU5 441 +acc MACH_ACC ACC 442 +esl_sarva MACH_ESL_SARVA ESL_SARVA 443 +xm250 MACH_XM250 XM250 444 +t6tc1xb MACH_T6TC1XB T6TC1XB 445 +ess710 MACH_ESS710 ESS710 446 mx31ads MACH_MX31ADS MX31ADS 447 himalaya MACH_HIMALAYA HIMALAYA 448 +bolfenk MACH_BOLFENK BOLFENK 449 +at91rm9200kr MACH_AT91RM9200KR AT91RM9200KR 450 edb9312 MACH_EDB9312 EDB9312 451 omap_generic MACH_OMAP_GENERIC OMAP_GENERIC 452 +aximx3 MACH_AXIMX3 AXIMX3 453 +eb67xdip MACH_EB67XDIP EB67XDIP 454 +webtxs MACH_WEBTXS WEBTXS 455 +hawk MACH_HAWK HAWK 456 +ccat91sbc001 MACH_CCAT91SBC001 CCAT91SBC001 457 +expresso MACH_EXPRESSO EXPRESSO 458 +h4000 MACH_H4000 H4000 459 +dino MACH_DINO DINO 460 +ml675k MACH_ML675K ML675K 461 edb9301 MACH_EDB9301 EDB9301 462 edb9315 MACH_EDB9315 EDB9315 463 +reciva_tt MACH_RECIVA_TT RECIVA_TT 464 +cstcb01 MACH_CSTCB01 CSTCB01 465 +cstcb1 MACH_CSTCB1 CSTCB1 466 +shadwell MACH_SHADWELL SHADWELL 467 +goepel263 MACH_GOEPEL263 GOEPEL263 468 +acq100 MACH_ACQ100 ACQ100 469 +mx1fs2 MACH_MX1FS2 MX1FS2 470 +hiptop_g1 MACH_HIPTOP_G1 HIPTOP_G1 471 +sparky MACH_SPARKY SPARKY 472 +ns9750 MACH_NS9750 NS9750 473 +phoenix MACH_PHOENIX PHOENIX 474 vr1000 MACH_VR1000 VR1000 475 +deisterpxa MACH_DEISTERPXA DEISTERPXA 476 +bcm1160 MACH_BCM1160 BCM1160 477 +pcm022 MACH_PCM022 PCM022 478 +adsgcx MACH_ADSGCX ADSGCX 479 +dreadnaught MACH_DREADNAUGHT DREADNAUGHT 480 +dm320 MACH_DM320 DM320 481 +markov MACH_MARKOV MARKOV 482 +cos7a400 MACH_COS7A400 COS7A400 483 +milano MACH_MILANO MILANO 484 +ue9328 MACH_UE9328 UE9328 485 +uex255 MACH_UEX255 UEX255 486 +ue2410 MACH_UE2410 UE2410 487 +a620 MACH_A620 A620 488 +ocelot MACH_OCELOT OCELOT 489 +cheetah MACH_CHEETAH CHEETAH 490 omap_perseus2 MACH_OMAP_PERSEUS2 OMAP_PERSEUS2 491 +zvue MACH_ZVUE ZVUE 492 +roverp1 MACH_ROVERP1 ROVERP1 493 +asidial2 MACH_ASIDIAL2 ASIDIAL2 494 +s3c24a0 MACH_S3C24A0 S3C24A0 495 e800 MACH_E800 E800 496 e750 MACH_E750 E750 497 +s3c5500 MACH_S3C5500 S3C5500 498 +smdk5500 MACH_SMDK5500 SMDK5500 499 +signalsync MACH_SIGNALSYNC SIGNALSYNC 500 +nbc MACH_NBC NBC 501 +kodiak MACH_KODIAK KODIAK 502 +netbookpro MACH_NETBOOKPRO NETBOOKPRO 503 +hw90200 MACH_HW90200 HW90200 504 +condor MACH_CONDOR CONDOR 505 +cup MACH_CUP CUP 506 +kite MACH_KITE KITE 507 scb9328 MACH_SCB9328 SCB9328 508 omap_h3 MACH_OMAP_H3 OMAP_H3 509 omap_h4 MACH_OMAP_H4 OMAP_H4 510 +n10 MACH_N10 N10 511 +montejade MACH_MONTAJADE MONTAJADE 512 +sg560 MACH_SG560 SG560 513 +dp1000 MACH_DP1000 DP1000 514 omap_osk MACH_OMAP_OSK OMAP_OSK 515 +rg100v3 MACH_RG100V3 RG100V3 516 +mx2ads MACH_MX2ADS MX2ADS 517 +pxa_kilo MACH_PXA_KILO PXA_KILO 518 +ixp4xx_eagle MACH_IXP4XX_EAGLE IXP4XX_EAGLE 519 tosa MACH_TOSA TOSA 520 +mb2520f MACH_MB2520F MB2520F 521 +emc1000 MACH_EMC1000 EMC1000 522 +tidsc25 MACH_TIDSC25 TIDSC25 523 +akcpmxl MACH_AKCPMXL AKCPMXL 524 +av3xx MACH_AV3XX AV3XX 525 avila MACH_AVILA AVILA 526 +pxa_mpm10 MACH_PXA_MPM10 PXA_MPM10 527 +pxa_kyanite MACH_PXA_KYANITE PXA_KYANITE 528 +sgold MACH_SGOLD SGOLD 529 +oscar MACH_OSCAR OSCAR 530 +epxa4usb2 MACH_EPXA4USB2 EPXA4USB2 531 +xsengine MACH_XSENGINE XSENGINE 532 +ip600 MACH_IP600 IP600 533 +mcan2 MACH_MCAN2 MCAN2 534 +ddi_blueridge MACH_DDI_BLUERIDGE DDI_BLUERIDGE 535 +skyminder MACH_SKYMINDER SKYMINDER 536 +lpd79520 MACH_LPD79520 LPD79520 537 edb9302 MACH_EDB9302 EDB9302 538 +hw90340 MACH_HW90340 HW90340 539 +cip_box MACH_CIP_BOX CIP_BOX 540 +ivpn MACH_IVPN IVPN 541 +rsoc2 MACH_RSOC2 RSOC2 542 husky MACH_HUSKY HUSKY 543 +boxer MACH_BOXER BOXER 544 shepherd MACH_SHEPHERD SHEPHERD 545 +aml42800aa MACH_AML42800AA AML42800AA 546 +lpc2294 MACH_LPC2294 LPC2294 548 +switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 +ens_cmu MACH_ENS_CMU ENS_CMU 550 +mm6_sdb MACH_MM6_SDB MM6_SDB 551 +saturn MACH_SATURN SATURN 552 +i30030evb MACH_I30030EVB I30030EVB 553 +mxc27530evb MACH_MXC27530EVB MXC27530EVB 554 +smdk2800 MACH_SMDK2800 SMDK2800 555 +mtwilson MACH_MTWILSON MTWILSON 556 +ziti MACH_ZITI ZITI 557 +grandfather MACH_GRANDFATHER GRANDFATHER 558 +tengine MACH_TENGINE TENGINE 559 +s3c2460 MACH_S3C2460 S3C2460 560 +pdm MACH_PDM PDM 561 h4700 MACH_H4700 H4700 562 +h6300 MACH_H6300 H6300 563 +rz1700 MACH_RZ1700 RZ1700 564 +a716 MACH_A716 A716 565 +estk2440a MACH_ESTK2440A ESTK2440A 566 +atwixp425 MACH_ATWIXP425 ATWIXP425 567 +csb336 MACH_CSB336 CSB336 568 +rirm2 MACH_RIRM2 RIRM2 569 +cx23518 MACH_CX23518 CX23518 570 +cx2351x MACH_CX2351X CX2351X 571 +computime MACH_COMPUTIME COMPUTIME 572 +izarus MACH_IZARUS IZARUS 573 +pxa_rts MACH_RTS RTS 574 +se5100 MACH_SE5100 SE5100 575 +s3c2510 MACH_S3C2510 S3C2510 576 +csb437tl MACH_CSB437TL CSB437TL 577 +slauson MACH_SLAUSON SLAUSON 578 +pearlriver MACH_PEARLRIVER PEARLRIVER 579 +tdc_p210 MACH_TDC_P210 TDC_P210 580 +sg580 MACH_SG580 SG580 581 +wrsbcarm7 MACH_WRSBCARM7 WRSBCARM7 582 +ipd MACH_IPD IPD 583 +pxa_dnp2110 MACH_PXA_DNP2110 PXA_DNP2110 584 +xaeniax MACH_XAENIAX XAENIAX 585 +somn4250 MACH_SOMN4250 SOMN4250 586 +pleb2 MACH_PLEB2 PLEB2 587 +cornwallis MACH_CORNWALLIS CORNWALLIS 588 +gurney_drv MACH_GURNEY_DRV GURNEY_DRV 589 +chaffee MACH_CHAFFEE CHAFFEE 590 +rms101 MACH_RMS101 RMS101 591 rx3715 MACH_RX3715 RX3715 592 +swift MACH_SWIFT SWIFT 593 +roverp7 MACH_ROVERP7 ROVERP7 594 +pr818s MACH_PR818S PR818S 595 +trxpro MACH_TRXPRO TRXPRO 596 nslu2 MACH_NSLU2 NSLU2 597 e400 MACH_E400 E400 598 +trab MACH_TRAB TRAB 599 +cmc_pu2 MACH_CMC_PU2 CMC_PU2 600 +fulcrum MACH_FULCRUM FULCRUM 601 +netgate42x MACH_NETGATE42X NETGATE42X 602 +str710 MACH_STR710 STR710 603 ixdpg425 MACH_IXDPG425 IXDPG425 604 +tomtomgo MACH_TOMTOMGO TOMTOMGO 605 versatile_ab MACH_VERSATILE_AB VERSATILE_AB 606 edb9307 MACH_EDB9307 EDB9307 607 +sg565 MACH_SG565 SG565 608 +lpd79524 MACH_LPD79524 LPD79524 609 +lpd79525 MACH_LPD79525 LPD79525 610 +rms100 MACH_RMS100 RMS100 611 kb9200 MACH_KB9200 KB9200 612 sx1 MACH_SX1 SX1 613 +hms39c7092 MACH_HMS39C7092 HMS39C7092 614 +armadillo MACH_ARMADILLO ARMADILLO 615 +ipcu MACH_IPCU IPCU 616 +loox720 MACH_LOOX720 LOOX720 617 ixdp465 MACH_IXDP465 IXDP465 618 ixdp2351 MACH_IXDP2351 IXDP2351 619 +adsvix MACH_ADSVIX ADSVIX 620 +dm270 MACH_DM270 DM270 621 +socltplus MACH_SOCLTPLUS SOCLTPLUS 622 +ecia MACH_ECIA ECIA 623 +cm4008 MACH_CM4008 CM4008 624 +p2001 MACH_P2001 P2001 625 +twister MACH_TWISTER TWISTER 626 +mudshark MACH_MUDSHARK MUDSHARK 627 +hb2 MACH_HB2 HB2 628 iq80332 MACH_IQ80332 IQ80332 629 +sendt MACH_SENDT SENDT 630 +mx2jazz MACH_MX2JAZZ MX2JAZZ 631 +multiio MACH_MULTIIO MULTIIO 632 +hrdisplay MACH_HRDISPLAY HRDISPLAY 633 +mxc27530ads MACH_MXC27530ADS MXC27530ADS 634 +trizeps3 MACH_TRIZEPS3 TRIZEPS3 635 +zefeerdza MACH_ZEFEERDZA ZEFEERDZA 636 +zefeerdzb MACH_ZEFEERDZB ZEFEERDZB 637 +zefeerdzg MACH_ZEFEERDZG ZEFEERDZG 638 +zefeerdzn MACH_ZEFEERDZN ZEFEERDZN 639 +zefeerdzq MACH_ZEFEERDZQ ZEFEERDZQ 640 gtwx5715 MACH_GTWX5715 GTWX5715 641 +astro_jack MACH_ASTRO_JACK ASTRO_JACK 643 +tip03 MACH_TIP03 TIP03 644 +a9200ec MACH_A9200EC A9200EC 645 +pnx0105 MACH_PNX0105 PNX0105 646 +adcpoecpu MACH_ADCPOECPU ADCPOECPU 647 csb637 MACH_CSB637 CSB637 648 +mb9200 MACH_MB9200 MB9200 650 +kulun MACH_KULUN KULUN 651 +snapper MACH_SNAPPER SNAPPER 652 +optima MACH_OPTIMA OPTIMA 653 +dlhsbc MACH_DLHSBC DLHSBC 654 +x30 MACH_X30 X30 655 n30 MACH_N30 N30 656 +manga_ks8695 MACH_MANGA_KS8695 MANGA_KS8695 657 +ajax MACH_AJAX AJAX 658 nec_mp900 MACH_NEC_MP900 NEC_MP900 659 +vvtk1000 MACH_VVTK1000 VVTK1000 661 kafa MACH_KAFA KAFA 662 +vvtk3000 MACH_VVTK3000 VVTK3000 663 +pimx1 MACH_PIMX1 PIMX1 664 +ollie MACH_OLLIE OLLIE 665 +skymax MACH_SKYMAX SKYMAX 666 +jazz MACH_JAZZ JAZZ 667 +tel_t3 MACH_TEL_T3 TEL_T3 668 +aisino_fcr255 MACH_AISINO_FCR255 AISINO_FCR255 669 +btweb MACH_BTWEB BTWEB 670 +dbg_lh79520 MACH_DBG_LH79520 DBG_LH79520 671 +cm41xx MACH_CM41XX CM41XX 672 ts72xx MACH_TS72XX TS72XX 673 +nggpxa MACH_NGGPXA NGGPXA 674 +csb535 MACH_CSB535 CSB535 675 +csb536 MACH_CSB536 CSB536 676 +pxa_trakpod MACH_PXA_TRAKPOD PXA_TRAKPOD 677 +praxis MACH_PRAXIS PRAXIS 678 +lh75411 MACH_LH75411 LH75411 679 otom MACH_OTOM OTOM 680 nexcoder_2440 MACH_NEXCODER_2440 NEXCODER_2440 681 +loox410 MACH_LOOX410 LOOX410 682 +westlake MACH_WESTLAKE WESTLAKE 683 +nsb MACH_NSB NSB 684 +esl_sarva_stn MACH_ESL_SARVA_STN ESL_SARVA_STN 685 +esl_sarva_tft MACH_ESL_SARVA_TFT ESL_SARVA_TFT 686 +esl_sarva_iad MACH_ESL_SARVA_IAD ESL_SARVA_IAD 687 +esl_sarva_acc MACH_ESL_SARVA_ACC ESL_SARVA_ACC 688 +typhoon MACH_TYPHOON TYPHOON 689 +cnav MACH_CNAV CNAV 690 +a730 MACH_A730 A730 691 +netstar MACH_NETSTAR NETSTAR 692 +supercon MACH_PHASEFALE_SUPERCON PHASEFALE_SUPERCON 693 +shiva1100 MACH_SHIVA1100 SHIVA1100 694 +etexsc MACH_ETEXSC ETEXSC 695 +ixdpg465 MACH_IXDPG465 IXDPG465 696 +a9m2410 MACH_A9M2410 A9M2410 697 +a9m2440 MACH_A9M2440 A9M2440 698 +a9m9750 MACH_A9M9750 A9M9750 699 +a9m9360 MACH_A9M9360 A9M9360 700 +unc90 MACH_UNC90 UNC90 701 eco920 MACH_ECO920 ECO920 702 +satview MACH_SATVIEW SATVIEW 703 roadrunner MACH_ROADRUNNER ROADRUNNER 704 at91rm9200ek MACH_AT91RM9200EK AT91RM9200EK 705 +gp32 MACH_GP32 GP32 706 +gem MACH_GEM GEM 707 +i858 MACH_I858 I858 708 +hx2750 MACH_HX2750 HX2750 709 +mxc91131evb MACH_MXC91131EVB MXC91131EVB 710 +p700 MACH_P700 P700 711 +cpe MACH_CPE CPE 712 spitz MACH_SPITZ SPITZ 713 +nimbra340 MACH_NIMBRA340 NIMBRA340 714 +lpc22xx MACH_LPC22XX LPC22XX 715 +omap_comet3 MACH_COMET3 COMET3 716 +omap_comet4 MACH_COMET4 COMET4 717 +csb625 MACH_CSB625 CSB625 718 +fortunet2 MACH_FORTUNET2 FORTUNET2 719 +s5h2200 MACH_S5H2200 S5H2200 720 +optorm920 MACH_OPTORM920 OPTORM920 721 +adsbitsyxb MACH_ADSBITSYXB ADSBITSYXB 722 adssphere MACH_ADSSPHERE ADSSPHERE 723 +adsportal MACH_ADSPORTAL ADSPORTAL 724 +ln2410sbc MACH_LN2410SBC LN2410SBC 725 +cb3rufc MACH_CB3RUFC CB3RUFC 726 +mp2usb MACH_MP2USB MP2USB 727 +ntnp425c MACH_NTNP425C NTNP425C 728 colibri MACH_COLIBRI COLIBRI 729 +pcm7220 MACH_PCM7220 PCM7220 730 gateway7001 MACH_GATEWAY7001 GATEWAY7001 731 pcm027 MACH_PCM027 PCM027 732 +cmpxa MACH_CMPXA CMPXA 733 anubis MACH_ANUBIS ANUBIS 734 +ite8152 MACH_ITE8152 ITE8152 735 +lpc3xxx MACH_LPC3XXX LPC3XXX 736 +puppeteer MACH_PUPPETEER PUPPETEER 737 +e570 MACH_E570 E570 739 +x50 MACH_X50 X50 740 +recon MACH_RECON RECON 741 +xboardgp8 MACH_XBOARDGP8 XBOARDGP8 742 +fpic2 MACH_FPIC2 FPIC2 743 akita MACH_AKITA AKITA 744 +a81 MACH_A81 A81 745 +svm_sc25x MACH_SVM_SC25X SVM_SC25X 746 +vt020 MACH_VADATECH020 VADATECH020 747 +tli MACH_TLI TLI 748 +edb9315lc MACH_EDB9315LC EDB9315LC 749 +passec MACH_PASSEC PASSEC 750 +ds_tiger MACH_DS_TIGER DS_TIGER 751 +e310 MACH_E310 E310 752 e330 MACH_E330 E330 753 +rt3000 MACH_RT3000 RT3000 754 nokia770 MACH_NOKIA770 NOKIA770 755 +pnx0106 MACH_PNX0106 PNX0106 756 +hx21xx MACH_HX21XX HX21XX 757 +faraday MACH_FARADAY FARADAY 758 +sbc9312 MACH_SBC9312 SBC9312 759 +batman MACH_BATMAN BATMAN 760 +jpd201 MACH_JPD201 JPD201 761 +mipsa MACH_MIPSA MIPSA 762 +kacom MACH_KACOM KACOM 763 +swarcocpu MACH_SWARCOCPU SWARCOCPU 764 +swarcodsl MACH_SWARCODSL SWARCODSL 765 +blueangel MACH_BLUEANGEL BLUEANGEL 766 +hairygrama MACH_HAIRYGRAMA HAIRYGRAMA 767 +banff MACH_BANFF BANFF 768 carmeva MACH_CARMEVA CARMEVA 769 +sam255 MACH_SAM255 SAM255 770 +ppm10 MACH_PPM10 PPM10 771 edb9315a MACH_EDB9315A EDB9315A 772 +sunset MACH_SUNSET SUNSET 773 stargate2 MACH_STARGATE2 STARGATE2 774 intelmote2 MACH_INTELMOTE2 INTELMOTE2 775 trizeps4 MACH_TRIZEPS4 TRIZEPS4 776 +mainstone2 MACH_MAINSTONE2 MAINSTONE2 777 +ez_ixp42x MACH_EZ_IXP42X EZ_IXP42X 778 +tapwave_zodiac MACH_TAPWAVE_ZODIAC TAPWAVE_ZODIAC 779 +universalmeter MACH_UNIVERSALMETER UNIVERSALMETER 780 +hicoarm9 MACH_HICOARM9 HICOARM9 781 pnx4008 MACH_PNX4008 PNX4008 782 +kws6000 MACH_KWS6000 KWS6000 783 +portux920t MACH_PORTUX920T PORTUX920T 784 +ez_x5 MACH_EZ_X5 EZ_X5 785 +omap_rudolph MACH_OMAP_RUDOLPH OMAP_RUDOLPH 786 cpuat91 MACH_CPUAT91 CPUAT91 787 +rea9200 MACH_REA9200 REA9200 788 +acts_pune_sa1110 MACH_ACTS_PUNE_SA1110 ACTS_PUNE_SA1110 789 +ixp425 MACH_IXP425 IXP425 790 +i30030ads MACH_I30030ADS I30030ADS 791 +perch MACH_PERCH PERCH 792 +eis05r1 MACH_EIS05R1 EIS05R1 793 +pepperpad MACH_PEPPERPAD PEPPERPAD 794 +sb3010 MACH_SB3010 SB3010 795 +rm9200 MACH_RM9200 RM9200 796 +dma03 MACH_DMA03 DMA03 797 +road_s101 MACH_ROAD_S101 ROAD_S101 798 iq81340sc MACH_IQ81340SC IQ81340SC 799 +iq_nextgen_b MACH_IQ_NEXTGEN_B IQ_NEXTGEN_B 800 iq81340mc MACH_IQ81340MC IQ81340MC 801 +iq_nextgen_d MACH_IQ_NEXTGEN_D IQ_NEXTGEN_D 802 +iq_nextgen_e MACH_IQ_NEXTGEN_E IQ_NEXTGEN_E 803 +mallow_at91 MACH_MALLOW_AT91 MALLOW_AT91 804 +cybertracker_i MACH_CYBERTRACKER_I CYBERTRACKER_I 805 +gesbc931x MACH_GESBC931X GESBC931X 806 +centipad MACH_CENTIPAD CENTIPAD 807 +armsoc MACH_ARMSOC ARMSOC 808 +se4200 MACH_SE4200 SE4200 809 +ems197a MACH_EMS197A EMS197A 810 micro9 MACH_MICRO9 MICRO9 811 micro9l MACH_MICRO9L MICRO9L 812 +uc5471dsp MACH_UC5471DSP UC5471DSP 813 +sj5471eng MACH_SJ5471ENG SJ5471ENG 814 +none MACH_CMPXA26X CMPXA26X 815 +nc1 MACH_NC NC 816 omap_palmte MACH_OMAP_PALMTE OMAP_PALMTE 817 +ajax52x MACH_AJAX52X AJAX52X 818 +siriustar MACH_SIRIUSTAR SIRIUSTAR 819 +iodata_hdlg MACH_IODATA_HDLG IODATA_HDLG 820 +at91rm9200utl MACH_AT91RM9200UTL AT91RM9200UTL 821 +biosafe MACH_BIOSAFE BIOSAFE 822 +mp1000 MACH_MP1000 MP1000 823 +parsy MACH_PARSY PARSY 824 +ccxp270 MACH_CCXP CCXP 825 +omap_gsample MACH_OMAP_GSAMPLE OMAP_GSAMPLE 826 realview_eb MACH_REALVIEW_EB REALVIEW_EB 827 +samoa MACH_SAMOA SAMOA 828 +palmt3 MACH_PALMT3 PALMT3 829 +i878 MACH_I878 I878 830 borzoi MACH_BORZOI BORZOI 831 +gecko MACH_GECKO GECKO 832 +ds101 MACH_DS101 DS101 833 +omap_palmtt2 MACH_OMAP_PALMTT2 OMAP_PALMTT2 834 palmld MACH_PALMLD PALMLD 835 +cc9c MACH_CC9C CC9C 836 +sbc1670 MACH_SBC1670 SBC1670 837 ixdp28x5 MACH_IXDP28X5 IXDP28X5 838 omap_palmtt MACH_OMAP_PALMTT OMAP_PALMTT 839 +ml696k MACH_ML696K ML696K 840 arcom_zeus MACH_ARCOM_ZEUS ARCOM_ZEUS 841 osiris MACH_OSIRIS OSIRIS 842 +maestro MACH_MAESTRO MAESTRO 843 palmte2 MACH_PALMTE2 PALMTE2 844 +ixbbm MACH_IXBBM IXBBM 845 mx27ads MACH_MX27ADS MX27ADS 846 +ax8004 MACH_AX8004 AX8004 847 at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848 loft MACH_LOFT LOFT 849 +magpie MACH_MAGPIE MAGPIE 850 mx21ads MACH_MX21ADS MX21ADS 851 +mb87m3400 MACH_MB87M3400 MB87M3400 852 +mguard_delta MACH_MGUARD_DELTA MGUARD_DELTA 853 +davinci_dvdp MACH_DAVINCI_DVDP DAVINCI_DVDP 854 +htcuniversal MACH_HTCUNIVERSAL HTCUNIVERSAL 855 +tpad MACH_TPAD TPAD 856 +roverp3 MACH_ROVERP3 ROVERP3 857 +jornada928 MACH_JORNADA928 JORNADA928 858 +mv88fxx81 MACH_MV88FXX81 MV88FXX81 859 +stmp36xx MACH_STMP36XX STMP36XX 860 +sxni79524 MACH_SXNI79524 SXNI79524 861 ams_delta MACH_AMS_DELTA AMS_DELTA 862 +uranium MACH_URANIUM URANIUM 863 +ucon MACH_UCON UCON 864 nas100d MACH_NAS100D NAS100D 865 +l083 MACH_L083_1000 L083_1000 866 +ezx MACH_EZX EZX 867 +pnx5220 MACH_PNX5220 PNX5220 868 +butte MACH_BUTTE BUTTE 869 +srm2 MACH_SRM2 SRM2 870 +dsbr MACH_DSBR DSBR 871 +crystalball MACH_CRYSTALBALL CRYSTALBALL 872 +tinypxa27x MACH_TINYPXA27X TINYPXA27X 873 +herbie MACH_HERBIE HERBIE 874 magician MACH_MAGICIAN MAGICIAN 875 +cm4002 MACH_CM4002 CM4002 876 +b4 MACH_B4 B4 877 +maui MACH_MAUI MAUI 878 +cybertracker_g MACH_CYBERTRACKER_G CYBERTRACKER_G 879 nxdkn MACH_NXDKN NXDKN 880 +mio8390 MACH_MIO8390 MIO8390 881 +omi_board MACH_OMI_BOARD OMI_BOARD 882 +mx21civ MACH_MX21CIV MX21CIV 883 +mahi_cdac MACH_MAHI_CDAC MAHI_CDAC 884 palmtx MACH_PALMTX PALMTX 885 s3c2413 MACH_S3C2413 S3C2413 887 +samsys_ep0 MACH_SAMSYS_EP0 SAMSYS_EP0 888 +wg302v1 MACH_WG302V1 WG302V1 889 wg302v2 MACH_WG302V2 WG302V2 890 +eb42x MACH_EB42X EB42X 891 +iq331es MACH_IQ331ES IQ331ES 892 +cosydsp MACH_COSYDSP COSYDSP 893 +uplat7d_proto MACH_UPLAT7D UPLAT7D 894 +ptdavinci MACH_PTDAVINCI PTDAVINCI 895 +mbus MACH_MBUS MBUS 896 +nadia2vb MACH_NADIA2VB NADIA2VB 897 +r1000 MACH_R1000 R1000 898 +hw90250 MACH_HW90250 HW90250 899 omap_2430sdp MACH_OMAP_2430SDP OMAP_2430SDP 900 davinci_evm MACH_DAVINCI_EVM DAVINCI_EVM 901 +omap_tornado MACH_OMAP_TORNADO OMAP_TORNADO 902 +olocreek MACH_OLOCREEK OLOCREEK 903 palmz72 MACH_PALMZ72 PALMZ72 904 nxdb500 MACH_NXDB500 NXDB500 905 apf9328 MACH_APF9328 APF9328 906 +omap_wipoq MACH_OMAP_WIPOQ OMAP_WIPOQ 907 +omap_twip MACH_OMAP_TWIP OMAP_TWIP 908 +treo650 MACH_TREO650 TREO650 909 +acumen MACH_ACUMEN ACUMEN 910 +xp100 MACH_XP100 XP100 911 +fs2410 MACH_FS2410 FS2410 912 +pxa270_cerf MACH_PXA270_CERF PXA270_CERF 913 +sq2ftlpalm MACH_SQ2FTLPALM SQ2FTLPALM 914 +bsemserver MACH_BSEMSERVER BSEMSERVER 915 +netclient MACH_NETCLIENT NETCLIENT 916 palmt5 MACH_PALMT5 PALMT5 917 palmtc MACH_PALMTC PALMTC 918 omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 +mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 +rea_cpu2 MACH_REA_2D REA_2D 921 +eti3e524 MACH_TI3E524 TI3E524 922 ateb9200 MACH_ATEB9200 ATEB9200 923 +auckland MACH_AUCKLAND AUCKLAND 924 +ak3220m MACH_AK3320M AK3320M 925 +duramax MACH_DURAMAX DURAMAX 926 n35 MACH_N35 N35 927 +pronghorn MACH_PRONGHORN PRONGHORN 928 +fundy MACH_FUNDY FUNDY 929 logicpd_pxa270 MACH_LOGICPD_PXA270 LOGICPD_PXA270 930 +cpu777 MACH_CPU777 CPU777 931 +simicon9201 MACH_SIMICON9201 SIMICON9201 932 +leap2_hpm MACH_LEAP2_HPM LEAP2_HPM 933 +cm922txa10 MACH_CM922TXA10 CM922TXA10 934 +sandgate MACH_PXA PXA 935 +sandgate2 MACH_SANDGATE2 SANDGATE2 936 +sandgate2g MACH_SANDGATE2G SANDGATE2G 937 +sandgate2p MACH_SANDGATE2P SANDGATE2P 938 +fred_jack MACH_FRED_JACK FRED_JACK 939 +ttg_color1 MACH_TTG_COLOR1 TTG_COLOR1 940 nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941 +netdcu8 MACH_NETDCU8 NETDCU8 942 +ng_fvx538 MACH_NG_FVX538 NG_FVX538 944 +ng_fvs338 MACH_NG_FVS338 NG_FVS338 945 +pnx4103 MACH_PNX4103 PNX4103 946 +hesdb MACH_HESDB HESDB 947 +xsilo MACH_XSILO XSILO 948 espresso MACH_ESPRESSO ESPRESSO 949 +emlc MACH_EMLC EMLC 950 +sisteron MACH_SISTERON SISTERON 951 rx1950 MACH_RX1950 RX1950 952 +tsc_venus MACH_TSC_VENUS TSC_VENUS 953 +ds101j MACH_DS101J DS101J 954 +mxc30030ads MACH_MXC30030ADS MXC30030ADS 955 +fujitsu_wimaxsoc MACH_FUJITSU_WIMAXSOC FUJITSU_WIMAXSOC 956 +dualpcmodem MACH_DUALPCMODEM DUALPCMODEM 957 gesbc9312 MACH_GESBC9312 GESBC9312 958 +htcapache MACH_HTCAPACHE HTCAPACHE 959 +ixdp435 MACH_IXDP435 IXDP435 960 +catprovt100 MACH_CATPROVT100 CATPROVT100 961 +picotux1xx MACH_PICOTUX1XX PICOTUX1XX 962 picotux2xx MACH_PICOTUX2XX PICOTUX2XX 963 dsmg600 MACH_DSMG600 DSMG600 964 +empc2 MACH_EMPC2 EMPC2 965 +ventura MACH_VENTURA VENTURA 966 +phidget_sbc MACH_PHIDGET_SBC PHIDGET_SBC 967 +ij3k MACH_IJ3K IJ3K 968 +pisgah MACH_PISGAH PISGAH 969 omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970 +sg720 MACH_SG720 SG720 971 +redfox MACH_REDFOX REDFOX 972 +mysh_ep9315_1 MACH_MYSH_EP9315_1 MYSH_EP9315_1 973 +tpf106 MACH_TPF106 TPF106 974 +at91rm9200kg MACH_AT91RM9200KG AT91RM9200KG 975 +rcmt2 MACH_SLEDB SLEDB 976 +ontrack MACH_ONTRACK ONTRACK 977 +pm1200 MACH_PM1200 PM1200 978 +ess24562 MACH_ESS24XXX ESS24XXX 979 +coremp7 MACH_COREMP7 COREMP7 980 +nexcoder_6446 MACH_NEXCODER_6446 NEXCODER_6446 981 +stvc8380 MACH_STVC8380 STVC8380 982 +teklynx MACH_TEKLYNX TEKLYNX 983 +carbonado MACH_CARBONADO CARBONADO 984 +sysmos_mp730 MACH_SYSMOS_MP730 SYSMOS_MP730 985 snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986 +pgigim MACH_PGIGIM PGIGIM 987 +ptx9160p2 MACH_PTX9160P2 PTX9160P2 988 +dcore1 MACH_DCORE1 DCORE1 989 +victorpxa MACH_VICTORPXA VICTORPXA 990 +mx2dtb MACH_MX2DTB MX2DTB 991 +pxa_irex_er0100 MACH_PXA_IREX_ER0100 PXA_IREX_ER0100 992 omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993 +bartec_deg MACH_BARTEC_DEG BARTEC_DEG 994 +hw50251 MACH_HW50251 HW50251 995 +ibox MACH_IBOX IBOX 996 +atlaslh7a404 MACH_ATLASLH7A404 ATLASLH7A404 997 +pt2026 MACH_PT2026 PT2026 998 +htcalpine MACH_HTCALPINE HTCALPINE 999 +bartec_vtu MACH_BARTEC_VTU BARTEC_VTU 1000 +vcoreii MACH_VCOREII VCOREII 1001 +pdnb3 MACH_PDNB3 PDNB3 1002 +htcbeetles MACH_HTCBEETLES HTCBEETLES 1003 +s3c6400 MACH_S3C6400 S3C6400 1004 +s3c2443 MACH_S3C2443 S3C2443 1005 +omap_ldk MACH_OMAP_LDK OMAP_LDK 1006 +smdk2460 MACH_SMDK2460 SMDK2460 1007 +smdk2440 MACH_SMDK2440 SMDK2440 1008 smdk2412 MACH_SMDK2412 SMDK2412 1009 +webbox MACH_WEBBOX WEBBOX 1010 +cwwndp MACH_CWWNDP CWWNDP 1011 +i839 MACH_DRAGON DRAGON 1012 +opendo_cpu_board MACH_OPENDO_CPU_BOARD OPENDO_CPU_BOARD 1013 +ccm2200 MACH_CCM2200 CCM2200 1014 +etwarm MACH_ETWARM ETWARM 1015 +m93030 MACH_M93030 M93030 1016 +cc7u MACH_CC7U CC7U 1017 +mtt_ranger MACH_MTT_RANGER MTT_RANGER 1018 +nexus MACH_NEXUS NEXUS 1019 +desman MACH_DESMAN DESMAN 1020 +bkde303 MACH_BKDE303 BKDE303 1021 smdk2413 MACH_SMDK2413 SMDK2413 1022 +aml_m7200 MACH_AML_M7200 AML_M7200 1023 aml_m5900 MACH_AML_M5900 AML_M5900 1024 +sg640 MACH_SG640 SG640 1025 +edg79524 MACH_EDG79524 EDG79524 1026 +ai2410 MACH_AI2410 AI2410 1027 +ixp465 MACH_IXP465 IXP465 1028 balloon3 MACH_BALLOON3 BALLOON3 1029 +heins MACH_HEINS HEINS 1030 +mpluseva MACH_MPLUSEVA MPLUSEVA 1031 +rt042 MACH_RT042 RT042 1032 +cwiem MACH_CWIEM CWIEM 1033 +cm_x270 MACH_CM_X270 CM_X270 1034 +cm_x255 MACH_CM_X255 CM_X255 1035 +esh_at91 MACH_ESH_AT91 ESH_AT91 1036 +sandgate3 MACH_SANDGATE3 SANDGATE3 1037 +primo MACH_PRIMO PRIMO 1038 +gemstone MACH_GEMSTONE GEMSTONE 1039 +pronghorn_metro MACH_PRONGHORNMETRO PRONGHORNMETRO 1040 +sidewinder MACH_SIDEWINDER SIDEWINDER 1041 +picomod1 MACH_PICOMOD1 PICOMOD1 1042 +sg590 MACH_SG590 SG590 1043 +akai9307 MACH_AKAI9307 AKAI9307 1044 +fontaine MACH_FONTAINE FONTAINE 1045 +wombat MACH_WOMBAT WOMBAT 1046 +acq300 MACH_ACQ300 ACQ300 1047 +mod272 MACH_MOD_270 MOD_270 1048 +vmc_vc0820 MACH_VC0820 VC0820 1049 +ani_aim MACH_ANI_AIM ANI_AIM 1050 +jellyfish MACH_JELLYFISH JELLYFISH 1051 +amanita MACH_AMANITA AMANITA 1052 +vlink MACH_VLINK VLINK 1053 +dexflex MACH_DEXFLEX DEXFLEX 1054 +eigen_ttq MACH_EIGEN_TTQ EIGEN_TTQ 1055 +arcom_titan MACH_ARCOM_TITAN ARCOM_TITAN 1056 +tabla MACH_TABLA TABLA 1057 +mdirac3 MACH_MDIRAC3 MDIRAC3 1058 +mrhfbp2 MACH_MRHFBP2 MRHFBP2 1059 +at91rm9200rb MACH_AT91RM9200RB AT91RM9200RB 1060 +ani_apm MACH_ANI_APM ANI_APM 1061 +ella1 MACH_ELLA1 ELLA1 1062 +inhand_pxa27x MACH_INHAND_PXA27X INHAND_PXA27X 1063 +inhand_pxa25x MACH_INHAND_PXA25X INHAND_PXA25X 1064 +empos_xm MACH_EMPOS_XM EMPOS_XM 1065 +empos MACH_EMPOS EMPOS 1066 +empos_tiny MACH_EMPOS_TINY EMPOS_TINY 1067 +empos_sm MACH_EMPOS_SM EMPOS_SM 1068 +egret MACH_EGRET EGRET 1069 +ostrich MACH_OSTRICH OSTRICH 1070 +n50 MACH_N50 N50 1071 ecbat91 MACH_ECBAT91 ECBAT91 1072 +stareast MACH_STAREAST STAREAST 1073 +dspg_dw MACH_DSPG_DW DSPG_DW 1074 onearm MACH_ONEARM ONEARM 1075 +mrg110_6 MACH_MRG110_6 MRG110_6 1076 +wrt300nv2 MACH_WRT300NV2 WRT300NV2 1077 +xm_bulverde MACH_XM_BULVERDE XM_BULVERDE 1078 +msm6100 MACH_MSM6100 MSM6100 1079 +eti_b1 MACH_ETI_B1 ETI_B1 1080 +za9l_series MACH_ZILOG_ZA9L ZILOG_ZA9L 1081 +bit2440 MACH_BIT2440 BIT2440 1082 +nbi MACH_NBI NBI 1083 smdk2443 MACH_SMDK2443 SMDK2443 1084 +vdavinci MACH_VDAVINCI VDAVINCI 1085 +atc6 MACH_ATC6 ATC6 1086 +multmdw MACH_MULTMDW MULTMDW 1087 +mba2440 MACH_MBA2440 MBA2440 1088 +ecsd MACH_ECSD ECSD 1089 +palmz31 MACH_PALMZ31 PALMZ31 1090 fsg MACH_FSG FSG 1091 +razor101 MACH_RAZOR101 RAZOR101 1092 +opera_tdm MACH_OPERA_TDM OPERA_TDM 1093 +comcerto MACH_COMCERTO COMCERTO 1094 +tb0319 MACH_TB0319 TB0319 1095 +kws8000 MACH_KWS8000 KWS8000 1096 +b2 MACH_B2 B2 1097 +lcl54 MACH_LCL54 LCL54 1098 at91sam9260ek MACH_AT91SAM9260EK AT91SAM9260EK 1099 glantank MACH_GLANTANK GLANTANK 1100 n2100 MACH_N2100 N2100 1101 +n4100 MACH_N4100 N4100 1102 +rsc4 MACH_VERTICAL_RSC4 VERTICAL_RSC4 1103 +sg8100 MACH_SG8100 SG8100 1104 +im42xx MACH_IM42XX IM42XX 1105 +ftxx MACH_FTXX FTXX 1106 +lwfusion MACH_LWFUSION LWFUSION 1107 qt2410 MACH_QT2410 QT2410 1108 kixrp435 MACH_KIXRP435 KIXRP435 1109 +ccw9c MACH_CCW9C CCW9C 1110 +dabhs MACH_DABHS DABHS 1111 +gzmx MACH_GZMX GZMX 1112 +ipnw100ap MACH_IPNW100AP IPNW100AP 1113 cc9p9360dev MACH_CC9P9360DEV CC9P9360DEV 1114 +cc9p9750dev MACH_CC9P9750DEV CC9P9750DEV 1115 +cc9p9360val MACH_CC9P9360VAL CC9P9360VAL 1116 +cc9p9750val MACH_CC9P9750VAL CC9P9750VAL 1117 +nx70v MACH_NX70V NX70V 1118 +at91rm9200df MACH_AT91RM9200DF AT91RM9200DF 1119 +se_pilot2 MACH_SE_PILOT2 SE_PILOT2 1120 +mtcn_t800 MACH_MTCN_T800 MTCN_T800 1121 +vcmx212 MACH_VCMX212 VCMX212 1122 +lynx MACH_LYNX LYNX 1123 +at91sam9260id MACH_AT91SAM9260ID AT91SAM9260ID 1124 +hw86052 MACH_HW86052 HW86052 1125 +pilz_pmi3 MACH_PILZ_PMI3 PILZ_PMI3 1126 edb9302a MACH_EDB9302A EDB9302A 1127 edb9307a MACH_EDB9307A EDB9307A 1128 +ct_dfs MACH_CT_DFS CT_DFS 1129 +pilz_pmi4 MACH_PILZ_PMI4 PILZ_PMI4 1130 +xceednp_ixp MACH_XCEEDNP_IXP XCEEDNP_IXP 1131 +smdk2442b MACH_SMDK2442B SMDK2442B 1132 +xnode MACH_XNODE XNODE 1133 +aidx270 MACH_AIDX270 AIDX270 1134 +rema MACH_REMA REMA 1135 +bps1000 MACH_BPS1000 BPS1000 1136 +hw90350 MACH_HW90350 HW90350 1137 omap_3430sdp MACH_OMAP_3430SDP OMAP_3430SDP 1138 +bluetouch MACH_BLUETOUCH BLUETOUCH 1139 vstms MACH_VSTMS VSTMS 1140 +xsbase270 MACH_XSBASE270 XSBASE270 1141 +at91sam9260ek_cn MACH_AT91SAM9260EK_CN AT91SAM9260EK_CN 1142 +adsturboxb MACH_ADSTURBOXB ADSTURBOXB 1143 +oti4110 MACH_OTI4110 OTI4110 1144 +hme_pxa MACH_HME_PXA HME_PXA 1145 +deisterdca MACH_DEISTERDCA DEISTERDCA 1146 +ces_ssem2 MACH_CES_SSEM2 CES_SSEM2 1147 +ces_mtr MACH_CES_MTR CES_MTR 1148 +tds_avng_sbc MACH_TDS_AVNG_SBC TDS_AVNG_SBC 1149 +everest MACH_EVEREST EVEREST 1150 +pnx4010 MACH_PNX4010 PNX4010 1151 +oxnas MACH_OXNAS OXNAS 1152 +fiori MACH_FIORI FIORI 1153 +ml1200 MACH_ML1200 ML1200 1154 +pecos MACH_PECOS PECOS 1155 +nb2xxx MACH_NB2XXX NB2XXX 1156 +hw6900 MACH_HW6900 HW6900 1157 +cdcs_quoll MACH_CDCS_QUOLL CDCS_QUOLL 1158 +quicksilver MACH_QUICKSILVER QUICKSILVER 1159 +uplat926 MACH_UPLAT926 UPLAT926 1160 +dep2410_dep2410 MACH_DEP2410_THOMAS DEP2410_THOMAS 1161 +dtk2410 MACH_DTK2410 DTK2410 1162 +chili MACH_CHILI CHILI 1163 +demeter MACH_DEMETER DEMETER 1164 +dionysus MACH_DIONYSUS DIONYSUS 1165 +as352x MACH_AS352X AS352X 1166 +service MACH_SERVICE SERVICE 1167 +cs_e9301 MACH_CS_E9301 CS_E9301 1168 micro9m MACH_MICRO9M MICRO9M 1169 +ia_mospck MACH_IA_MOSPCK IA_MOSPCK 1170 +ql201b MACH_QL201B QL201B 1171 +bbm MACH_BBM BBM 1174 +exxx MACH_EXXX EXXX 1175 +wma11b MACH_WMA11B WMA11B 1176 +pelco_atlas MACH_PELCO_ATLAS PELCO_ATLAS 1177 +g500 MACH_G500 G500 1178 bug MACH_BUG BUG 1179 +mx33ads MACH_MX33ADS MX33ADS 1180 +chub MACH_CHUB CHUB 1181 +neo1973_gta01 MACH_NEO1973_GTA01 NEO1973_GTA01 1182 +w90n740 MACH_W90N740 W90N740 1183 +medallion_sa2410 MACH_MEDALLION_SA2410 MEDALLION_SA2410 1184 +ia_cpu_9200_2 MACH_IA_CPU_9200_2 IA_CPU_9200_2 1185 +dimmrm9200 MACH_DIMMRM9200 DIMMRM9200 1186 +pm9261 MACH_PM9261 PM9261 1187 +ml7304 MACH_ML7304 ML7304 1189 +ucp250 MACH_UCP250 UCP250 1190 +intboard MACH_INTBOARD INTBOARD 1191 +gulfstream MACH_GULFSTREAM GULFSTREAM 1192 +labquest MACH_LABQUEST LABQUEST 1193 +vcmx313 MACH_VCMX313 VCMX313 1194 +urg200 MACH_URG200 URG200 1195 +cpux255lcdnet MACH_CPUX255LCDNET CPUX255LCDNET 1196 +netdcu9 MACH_NETDCU9 NETDCU9 1197 +netdcu10 MACH_NETDCU10 NETDCU10 1198 +dspg_dga MACH_DSPG_DGA DSPG_DGA 1199 +dspg_dvw MACH_DSPG_DVW DSPG_DVW 1200 +solos MACH_SOLOS SOLOS 1201 at91sam9263ek MACH_AT91SAM9263EK AT91SAM9263EK 1202 +osstbox MACH_OSSTBOX OSSTBOX 1203 +kbat9261 MACH_KBAT9261 KBAT9261 1204 +ct1100 MACH_CT1100 CT1100 1205 +akcppxa MACH_AKCPPXA AKCPPXA 1206 +ochaya1020 MACH_OCHAYA1020 OCHAYA1020 1207 +hitrack MACH_HITRACK HITRACK 1208 +syme1 MACH_SYME1 SYME1 1209 +syhl1 MACH_SYHL1 SYHL1 1210 +empca400 MACH_EMPCA400 EMPCA400 1211 em7210 MACH_EM7210 EM7210 1212 +htchermes MACH_HTCHERMES HTCHERMES 1213 +eti_c1 MACH_ETI_C1 ETI_C1 1214 +ac100 MACH_AC100 AC100 1216 +sneetch MACH_SNEETCH SNEETCH 1217 +studentmate MACH_STUDENTMATE STUDENTMATE 1218 +zir2410 MACH_ZIR2410 ZIR2410 1219 +zir2413 MACH_ZIR2413 ZIR2413 1220 +dlonip3 MACH_DLONIP3 DLONIP3 1221 +instream MACH_INSTREAM INSTREAM 1222 +ambarella MACH_AMBARELLA AMBARELLA 1223 +nevis MACH_NEVIS NEVIS 1224 +htc_trinity MACH_HTC_TRINITY HTC_TRINITY 1225 +ql202b MACH_QL202B QL202B 1226 vpac270 MACH_VPAC270 VPAC270 1227 +rd129 MACH_RD129 RD129 1228 +htcwizard MACH_HTCWIZARD HTCWIZARD 1229 treo680 MACH_TREO680 TREO680 1230 +tecon_tmezon MACH_TECON_TMEZON TECON_TMEZON 1231 zylonite MACH_ZYLONITE ZYLONITE 1233 +gene1270 MACH_GENE1270 GENE1270 1234 +zir2412 MACH_ZIR2412 ZIR2412 1235 mx31lite MACH_MX31LITE MX31LITE 1236 +t700wx MACH_T700WX T700WX 1237 +vf100 MACH_VF100 VF100 1238 +nsb2 MACH_NSB2 NSB2 1239 +nxhmi_bb MACH_NXHMI_BB NXHMI_BB 1240 +nxhmi_re MACH_NXHMI_RE NXHMI_RE 1241 +n4100pro MACH_N4100PRO N4100PRO 1242 +sam9260 MACH_SAM9260 SAM9260 1243 +omap_treo600 MACH_OMAP_TREO600 OMAP_TREO600 1244 +indy2410 MACH_INDY2410 INDY2410 1245 +nelt_a MACH_NELT_A NELT_A 1246 +n311 MACH_N311 N311 1248 +at91sam9260vgk MACH_AT91SAM9260VGK AT91SAM9260VGK 1249 +at91leppe MACH_AT91LEPPE AT91LEPPE 1250 +at91lepccn MACH_AT91LEPCCN AT91LEPCCN 1251 +apc7100 MACH_APC7100 APC7100 1252 +stargazer MACH_STARGAZER STARGAZER 1253 +sonata MACH_SONATA SONATA 1254 +schmoogie MACH_SCHMOOGIE SCHMOOGIE 1255 +aztool MACH_AZTOOL AZTOOL 1256 mioa701 MACH_MIOA701 MIOA701 1257 +sxni9260 MACH_SXNI9260 SXNI9260 1258 +mxc27520evb MACH_MXC27520EVB MXC27520EVB 1259 armadillo5x0 MACH_ARMADILLO5X0 ARMADILLO5X0 1260 +mb9260 MACH_MB9260 MB9260 1261 +mb9263 MACH_MB9263 MB9263 1262 +ipac9302 MACH_IPAC9302 IPAC9302 1263 cc9p9360js MACH_CC9P9360JS CC9P9360JS 1264 +gallium MACH_GALLIUM GALLIUM 1265 +msc2410 MACH_MSC2410 MSC2410 1266 +ghi270 MACH_GHI270 GHI270 1267 +davinci_leonardo MACH_DAVINCI_LEONARDO DAVINCI_LEONARDO 1268 +oiab MACH_OIAB OIAB 1269 smdk6400 MACH_SMDK6400 SMDK6400 1270 nokia_n800 MACH_NOKIA_N800 NOKIA_N800 1271 +greenphone MACH_GREENPHONE GREENPHONE 1272 +compex42x MACH_COMPEXWP18 COMPEXWP18 1273 +xmate MACH_XMATE XMATE 1274 +energizer MACH_ENERGIZER ENERGIZER 1275 +ime1 MACH_IME1 IME1 1276 +sweda_tms MACH_SWEDATMS SWEDATMS 1277 +ntnp435c MACH_NTNP435C NTNP435C 1278 +spectro2 MACH_SPECTRO2 SPECTRO2 1279 +h6039 MACH_H6039 H6039 1280 ep80219 MACH_EP80219 EP80219 1281 +samoa_ii MACH_SAMOA_II SAMOA_II 1282 +cwmxl MACH_CWMXL CWMXL 1283 +as9200 MACH_AS9200 AS9200 1284 +sfx1149 MACH_SFX1149 SFX1149 1285 +navi010 MACH_NAVI010 NAVI010 1286 +multmdp MACH_MULTMDP MULTMDP 1287 +scb9520 MACH_SCB9520 SCB9520 1288 +htcathena MACH_HTCATHENA HTCATHENA 1289 +xp179 MACH_XP179 XP179 1290 +h4300 MACH_H4300 H4300 1291 goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292 +mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293 +adsbitsyg5 MACH_ADSBITSYG5 ADSBITSYG5 1294 +adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295 +mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296 em_x270 MACH_EM_X270 EM_X270 1297 +tpp302 MACH_TPP302 TPP302 1298 +tpp104 MACH_TPM104 TPM104 1299 +tpm102 MACH_TPM102 TPM102 1300 +tpm109 MACH_TPM109 TPM109 1301 +fbxo1 MACH_FBXO1 FBXO1 1302 +hxd8 MACH_HXD8 HXD8 1303 neo1973_gta02 MACH_NEO1973_GTA02 NEO1973_GTA02 1304 +emtest MACH_EMTEST EMTEST 1305 +ad6900 MACH_AD6900 AD6900 1306 +europa MACH_EUROPA EUROPA 1307 +metroconnect MACH_METROCONNECT METROCONNECT 1308 +ez_s2410 MACH_EZ_S2410 EZ_S2410 1309 +ez_s2440 MACH_EZ_S2440 EZ_S2440 1310 +ez_ep9312 MACH_EZ_EP9312 EZ_EP9312 1311 +ez_ep9315 MACH_EZ_EP9315 EZ_EP9315 1312 +ez_x7 MACH_EZ_X7 EZ_X7 1313 +godotdb MACH_GODOTDB GODOTDB 1314 +mistral MACH_MISTRAL MISTRAL 1315 +msm MACH_MSM MSM 1316 +ct5910 MACH_CT5910 CT5910 1317 +ct5912 MACH_CT5912 CT5912 1318 +argonst_mp MACH_HYNET_INE HYNET_INE 1319 +hynet_app MACH_HYNET_APP HYNET_APP 1320 +msm7200 MACH_MSM7200 MSM7200 1321 +msm7600 MACH_MSM7600 MSM7600 1322 +ceb255 MACH_CEB255 CEB255 1323 +ciel MACH_CIEL CIEL 1324 +slm5650 MACH_SLM5650 SLM5650 1325 at91sam9rlek MACH_AT91SAM9RLEK AT91SAM9RLEK 1326 +comtech_router MACH_COMTECH_ROUTER COMTECH_ROUTER 1327 +sbc2410x MACH_SBC2410X SBC2410X 1328 +at4x0bd MACH_AT4X0BD AT4X0BD 1329 +cbifr MACH_CBIFR CBIFR 1330 +arcom_quantum MACH_ARCOM_QUANTUM ARCOM_QUANTUM 1331 +matrix520 MACH_MATRIX520 MATRIX520 1332 +matrix510 MACH_MATRIX510 MATRIX510 1333 +matrix500 MACH_MATRIX500 MATRIX500 1334 +m501 MACH_M501 M501 1335 +aaeon1270 MACH_AAEON1270 AAEON1270 1336 +matrix500ev MACH_MATRIX500EV MATRIX500EV 1337 +pac500 MACH_PAC500 PAC500 1338 +pnx8181 MACH_PNX8181 PNX8181 1339 colibri320 MACH_COLIBRI320 COLIBRI320 1340 +aztoolbb MACH_AZTOOLBB AZTOOLBB 1341 +aztoolg2 MACH_AZTOOLG2 AZTOOLG2 1342 +dvlhost MACH_DVLHOST DVLHOST 1343 +zir9200 MACH_ZIR9200 ZIR9200 1344 +zir9260 MACH_ZIR9260 ZIR9260 1345 +cocopah MACH_COCOPAH COCOPAH 1346 +nds MACH_NDS NDS 1347 +rosencrantz MACH_ROSENCRANTZ ROSENCRANTZ 1348 +fttx_odsc MACH_FTTX_ODSC FTTX_ODSC 1349 +classe_r6904 MACH_CLASSE_R6904 CLASSE_R6904 1350 cam60 MACH_CAM60 CAM60 1351 +mxc30031ads MACH_MXC30031ADS MXC30031ADS 1352 +datacall MACH_DATACALL DATACALL 1353 at91eb01 MACH_AT91EB01 AT91EB01 1354 +rty MACH_RTY RTY 1355 +dwl2100 MACH_DWL2100 DWL2100 1356 +vinsi MACH_VINSI VINSI 1357 db88f5281 MACH_DB88F5281 DB88F5281 1358 csb726 MACH_CSB726 CSB726 1359 +tik27 MACH_TIK27 TIK27 1360 +mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361 +rirm3 MACH_RIRM3 RIRM3 1362 +pelco_odyssey MACH_PELCO_ODYSSEY PELCO_ODYSSEY 1363 +adx_abox MACH_ADX_ABOX ADX_ABOX 1365 +adx_tpid MACH_ADX_TPID ADX_TPID 1366 +minicheck MACH_MINICHECK MINICHECK 1367 +idam MACH_IDAM IDAM 1368 +mario_mx MACH_MARIO_MX MARIO_MX 1369 +vi1888 MACH_VI1888 VI1888 1370 +zr4230 MACH_ZR4230 ZR4230 1371 +t1_ix_blue MACH_T1_IX_BLUE T1_IX_BLUE 1372 +syhq2 MACH_SYHQ2 SYHQ2 1373 +computime_r3 MACH_COMPUTIME_R3 COMPUTIME_R3 1374 +oratis MACH_ORATIS ORATIS 1375 +mikko MACH_MIKKO MIKKO 1376 +holon MACH_HOLON HOLON 1377 +olip8 MACH_OLIP8 OLIP8 1378 +ghi270hg MACH_GHI270HG GHI270HG 1379 davinci_dm6467_evm MACH_DAVINCI_DM6467_EVM DAVINCI_DM6467_EVM 1380 davinci_dm355_evm MACH_DAVINCI_DM355_EVM DAVINCI_DM355_EVM 1381 +blackriver MACH_BLACKRIVER BLACKRIVER 1383 +sandgate_wp MACH_SANDGATEWP SANDGATEWP 1384 +cdotbwsg MACH_CDOTBWSG CDOTBWSG 1385 +quark963 MACH_QUARK963 QUARK963 1386 +csb735 MACH_CSB735 CSB735 1387 littleton MACH_LITTLETON LITTLETON 1388 +mio_p550 MACH_MIO_P550 MIO_P550 1389 +motion2440 MACH_MOTION2440 MOTION2440 1390 +imm500 MACH_IMM500 IMM500 1391 +homematic MACH_HOMEMATIC HOMEMATIC 1392 +ermine MACH_ERMINE ERMINE 1393 +kb9202b MACH_KB9202B KB9202B 1394 +hs1xx MACH_HS1XX HS1XX 1395 +studentmate2440 MACH_STUDENTMATE2440 STUDENTMATE2440 1396 +arvoo_l1_z1 MACH_ARVOO_L1_Z1 ARVOO_L1_Z1 1397 +dep2410k MACH_DEP2410K DEP2410K 1398 +xxsvideo MACH_XXSVIDEO XXSVIDEO 1399 +im4004 MACH_IM4004 IM4004 1400 +ochaya1050 MACH_OCHAYA1050 OCHAYA1050 1401 +lep9261 MACH_LEP9261 LEP9261 1402 +svenmeb MACH_SVENMEB SVENMEB 1403 +fortunet2ne MACH_FORTUNET2NE FORTUNET2NE 1404 +nxhx MACH_NXHX NXHX 1406 realview_pb11mp MACH_REALVIEW_PB11MP REALVIEW_PB11MP 1407 +ids500 MACH_IDS500 IDS500 1408 +ors_n725 MACH_ORS_N725 ORS_N725 1409 +hsdarm MACH_HSDARM HSDARM 1410 +sha_pon003 MACH_SHA_PON003 SHA_PON003 1411 +sha_pon004 MACH_SHA_PON004 SHA_PON004 1412 +sha_pon007 MACH_SHA_PON007 SHA_PON007 1413 +sha_pon011 MACH_SHA_PON011 SHA_PON011 1414 +h6042 MACH_H6042 H6042 1415 +h6043 MACH_H6043 H6043 1416 +looxc550 MACH_LOOXC550 LOOXC550 1417 +cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418 +app3xx MACH_APP3XX APP3XX 1419 +sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420 +treo700p MACH_TREO700P TREO700P 1421 +treo700w MACH_TREO700W TREO700W 1422 +treo750 MACH_TREO750 TREO750 1423 +treo755p MACH_TREO755P TREO755P 1424 +ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425 +sarge MACH_SARGE SARGE 1426 +a696 MACH_A696 A696 1427 +turtle1916 MACH_TURTLE TURTLE 1428 mx27_3ds MACH_MX27_3DS MX27_3DS 1430 +bishop MACH_BISHOP BISHOP 1431 +pxx MACH_PXX PXX 1432 +redwood MACH_REDWOOD REDWOOD 1433 +omap_2430dlp MACH_OMAP_2430DLP OMAP_2430DLP 1436 +omap_2430osk MACH_OMAP_2430OSK OMAP_2430OSK 1437 +sardine MACH_SARDINE SARDINE 1438 halibut MACH_HALIBUT HALIBUT 1439 trout MACH_TROUT TROUT 1440 +goldfish MACH_GOLDFISH GOLDFISH 1441 +gesbc2440 MACH_GESBC2440 GESBC2440 1442 +nomad MACH_NOMAD NOMAD 1443 +rosalind MACH_ROSALIND ROSALIND 1444 +cc9p9215 MACH_CC9P9215 CC9P9215 1445 +cc9p9210 MACH_CC9P9210 CC9P9210 1446 +cc9p9215js MACH_CC9P9215JS CC9P9215JS 1447 +cc9p9210js MACH_CC9P9210JS CC9P9210JS 1448 +nasffe MACH_NASFFE NASFFE 1449 +tn2x0bd MACH_TN2X0BD TN2X0BD 1450 +gwmpxa MACH_GWMPXA GWMPXA 1451 +exyplus MACH_EXYPLUS EXYPLUS 1452 +jadoo21 MACH_JADOO21 JADOO21 1453 +looxn560 MACH_LOOXN560 LOOXN560 1454 +bonsai MACH_BONSAI BONSAI 1455 +adsmilgato MACH_ADSMILGATO ADSMILGATO 1456 +gba MACH_GBA GBA 1457 +h6044 MACH_H6044 H6044 1458 +app MACH_APP APP 1459 tct_hammer MACH_TCT_HAMMER TCT_HAMMER 1460 herald MACH_HERALD HERALD 1461 +artemis MACH_ARTEMIS ARTEMIS 1462 +htctitan MACH_HTCTITAN HTCTITAN 1463 +qranium MACH_QRANIUM QRANIUM 1464 +adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465 +adx_medcom MACH_ADX_MEDCOM ADX_MEDCOM 1466 +bboard MACH_BBOARD BBOARD 1467 +cambria MACH_CAMBRIA CAMBRIA 1468 +mt7xxx MACH_MT7XXX MT7XXX 1469 +matrix512 MACH_MATRIX512 MATRIX512 1470 +matrix522 MACH_MATRIX522 MATRIX522 1471 +ipac5010 MACH_IPAC5010 IPAC5010 1472 +sakura MACH_SAKURA SAKURA 1473 +grocx MACH_GROCX GROCX 1474 +pm9263 MACH_PM9263 PM9263 1475 sim_one MACH_SIM_ONE SIM_ONE 1476 +acq132 MACH_ACQ132 ACQ132 1477 +datr MACH_DATR DATR 1478 +actux1 MACH_ACTUX1 ACTUX1 1479 +actux2 MACH_ACTUX2 ACTUX2 1480 +actux3 MACH_ACTUX3 ACTUX3 1481 +flexit MACH_FLEXIT FLEXIT 1482 +bh2x0bd MACH_BH2X0BD BH2X0BD 1483 +atb2002 MACH_ATB2002 ATB2002 1484 +xenon MACH_XENON XENON 1485 +fm607 MACH_FM607 FM607 1486 +matrix514 MACH_MATRIX514 MATRIX514 1487 +matrix524 MACH_MATRIX524 MATRIX524 1488 +inpod MACH_INPOD INPOD 1489 jive MACH_JIVE JIVE 1490 +tll_mx21 MACH_TLL_MX21 TLL_MX21 1491 +sbc2800 MACH_SBC2800 SBC2800 1492 +cc7ucamry MACH_CC7UCAMRY CC7UCAMRY 1493 +ubisys_p9_sc15 MACH_UBISYS_P9_SC15 UBISYS_P9_SC15 1494 +ubisys_p9_ssc2d10 MACH_UBISYS_P9_SSC2D10 UBISYS_P9_SSC2D10 1495 +ubisys_p9_rcu3 MACH_UBISYS_P9_RCU3 UBISYS_P9_RCU3 1496 +aml_m8000 MACH_AML_M8000 AML_M8000 1497 +snapper_270 MACH_SNAPPER_270 SNAPPER_270 1498 +omap_bbx MACH_OMAP_BBX OMAP_BBX 1499 +ucn2410 MACH_UCN2410 UCN2410 1500 sam9_l9260 MACH_SAM9_L9260 SAM9_L9260 1501 +eti_c2 MACH_ETI_C2 ETI_C2 1502 +avalanche MACH_AVALANCHE AVALANCHE 1503 realview_pb1176 MACH_REALVIEW_PB1176 REALVIEW_PB1176 1504 +dp1500 MACH_DP1500 DP1500 1505 +apple_iphone MACH_APPLE_IPHONE APPLE_IPHONE 1506 yl9200 MACH_YL9200 YL9200 1507 rd88f5182 MACH_RD88F5182 RD88F5182 1508 kurobox_pro MACH_KUROBOX_PRO KUROBOX_PRO 1509 +se_poet MACH_SE_POET SE_POET 1510 mx31_3ds MACH_MX31_3DS MX31_3DS 1511 +r270 MACH_R270 R270 1512 +armour21 MACH_ARMOUR21 ARMOUR21 1513 +dt2 MACH_DT2 DT2 1514 +vt4 MACH_VT4 VT4 1515 +tyco320 MACH_TYCO320 TYCO320 1516 +adma MACH_ADMA ADMA 1517 +wp188 MACH_WP188 WP188 1518 +corsica MACH_CORSICA CORSICA 1519 +bigeye MACH_BIGEYE BIGEYE 1520 +tll5000 MACH_TLL5000 TLL5000 1522 +bebot MACH_BEBOT BEBOT 1523 qong MACH_QONG QONG 1524 +tcompact MACH_TCOMPACT TCOMPACT 1525 +puma5 MACH_PUMA5 PUMA5 1526 +elara MACH_ELARA ELARA 1527 +ellington MACH_ELLINGTON ELLINGTON 1528 +xda_atom MACH_XDA_ATOM XDA_ATOM 1529 +energizer2 MACH_ENERGIZER2 ENERGIZER2 1530 +odin MACH_ODIN ODIN 1531 +actux4 MACH_ACTUX4 ACTUX4 1532 +esl_omap MACH_ESL_OMAP ESL_OMAP 1533 omap2evm MACH_OMAP2EVM OMAP2EVM 1534 omap3evm MACH_OMAP3EVM OMAP3EVM 1535 +adx_pcu57 MACH_ADX_PCU57 ADX_PCU57 1536 +monaco MACH_MONACO MONACO 1537 +levante MACH_LEVANTE LEVANTE 1538 +tmxipx425 MACH_TMXIPX425 TMXIPX425 1539 +leep MACH_LEEP LEEP 1540 +raad MACH_RAAD RAAD 1541 dns323 MACH_DNS323 DNS323 1542 +ap1000 MACH_AP1000 AP1000 1543 +a9sam6432 MACH_A9SAM6432 A9SAM6432 1544 +shiny MACH_SHINY SHINY 1545 omap3_beagle MACH_OMAP3_BEAGLE OMAP3_BEAGLE 1546 +csr_bdb2 MACH_CSR_BDB2 CSR_BDB2 1547 nokia_n810 MACH_NOKIA_N810 NOKIA_N810 1548 +c270 MACH_C270 C270 1549 +sentry MACH_SENTRY SENTRY 1550 pcm038 MACH_PCM038 PCM038 1551 +anc300 MACH_ANC300 ANC300 1552 +htckaiser MACH_HTCKAISER HTCKAISER 1553 +sbat100 MACH_SBAT100 SBAT100 1554 +modunorm MACH_MODUNORM MODUNORM 1555 +pelos_twarm MACH_PELOS_TWARM PELOS_TWARM 1556 +flank MACH_FLANK FLANK 1557 +sirloin MACH_SIRLOIN SIRLOIN 1558 +brisket MACH_BRISKET BRISKET 1559 +chuck MACH_CHUCK CHUCK 1560 +otter MACH_OTTER OTTER 1561 +davinci_ldk MACH_DAVINCI_LDK DAVINCI_LDK 1562 +phreedom MACH_PHREEDOM PHREEDOM 1563 +sg310 MACH_SG310 SG310 1564 ts209 MACH_TS209 TS209 1565 at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566 +tion9315 MACH_TION9315 TION9315 1567 +mast MACH_MAST MAST 1568 +pfw MACH_PFW PFW 1569 +yl_p2440 MACH_YL_P2440 YL_P2440 1570 +zsbc32 MACH_ZSBC32 ZSBC32 1571 +omap_pace2 MACH_OMAP_PACE2 OMAP_PACE2 1572 +imx_pace2 MACH_IMX_PACE2 IMX_PACE2 1573 mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574 +mx37_3ds MACH_MX37_3DS MX37_3DS 1575 +rcc MACH_RCC RCC 1576 +dmp MACH_ARM9 ARM9 1577 vision_ep9307 MACH_VISION_EP9307 VISION_EP9307 1578 +scly1000 MACH_SCLY1000 SCLY1000 1579 +fontel_ep MACH_FONTEL_EP FONTEL_EP 1580 +voiceblue3g MACH_VOICEBLUE3G VOICEBLUE3G 1581 +tt9200 MACH_TT9200 TT9200 1582 +digi2410 MACH_DIGI2410 DIGI2410 1583 terastation_pro2 MACH_TERASTATION_PRO2 TERASTATION_PRO2 1584 linkstation_pro MACH_LINKSTATION_PRO LINKSTATION_PRO 1585 +motorola_a780 MACH_MOTOROLA_A780 MOTOROLA_A780 1587 +motorola_e6 MACH_MOTOROLA_E6 MOTOROLA_E6 1588 +motorola_e2 MACH_MOTOROLA_E2 MOTOROLA_E2 1589 +motorola_e680 MACH_MOTOROLA_E680 MOTOROLA_E680 1590 +ur2410 MACH_UR2410 UR2410 1591 +tas9261 MACH_TAS9261 TAS9261 1592 +davinci_hermes_hd MACH_HERMES_HD HERMES_HD 1593 +davinci_perseo_hd MACH_PERSEO_HD PERSEO_HD 1594 +stargazer2 MACH_STARGAZER2 STARGAZER2 1595 e350 MACH_E350 E350 1596 +wpcm450 MACH_WPCM450 WPCM450 1597 +cartesio MACH_CARTESIO CARTESIO 1598 +toybox MACH_TOYBOX TOYBOX 1599 +tx27 MACH_TX27 TX27 1600 ts409 MACH_TS409 TS409 1601 +p300 MACH_P300 P300 1602 +xdacomet MACH_XDACOMET XDACOMET 1603 +dexflex2 MACH_DEXFLEX2 DEXFLEX2 1604 +ow MACH_OW OW 1605 +armebs3 MACH_ARMEBS3 ARMEBS3 1606 +u3 MACH_U3 U3 1607 +smdk2450 MACH_SMDK2450 SMDK2450 1608 rsi_ews MACH_RSI_EWS RSI_EWS 1609 +tnb MACH_TNB TNB 1610 +toepath MACH_TOEPATH TOEPATH 1611 +kb9263 MACH_KB9263 KB9263 1612 +mt7108 MACH_MT7108 MT7108 1613 +smtr2440 MACH_SMTR2440 SMTR2440 1614 +manao MACH_MANAO MANAO 1615 cm_x300 MACH_CM_X300 CM_X300 1616 +gulfstream_kp MACH_GULFSTREAM_KP GULFSTREAM_KP 1617 +lanreadyfn522 MACH_LANREADYFN522 LANREADYFN522 1618 +arma37 MACH_ARMA37 ARMA37 1619 +mendel MACH_MENDEL MENDEL 1620 +pelco_iliad MACH_PELCO_ILIAD PELCO_ILIAD 1621 +unit2p MACH_UNIT2P UNIT2P 1622 +inc20otter MACH_INC20OTTER INC20OTTER 1623 at91sam9g20ek MACH_AT91SAM9G20EK AT91SAM9G20EK 1624 +sc_ge2 MACH_STORCENTER STORCENTER 1625 smdk6410 MACH_SMDK6410 SMDK6410 1626 u300 MACH_U300 U300 1627 +u500 MACH_U500 U500 1628 +ds9260 MACH_DS9260 DS9260 1629 +riverrock MACH_RIVERROCK RIVERROCK 1630 +scibath MACH_SCIBATH SCIBATH 1631 +at91sam7se MACH_AT91SAM7SE512EK AT91SAM7SE512EK 1632 wrt350n_v2 MACH_WRT350N_V2 WRT350N_V2 1633 +multimedia MACH_MULTIMEDIA MULTIMEDIA 1634 +marvin MACH_MARVIN MARVIN 1635 +x500 MACH_X500 X500 1636 +awlug4lcu MACH_AWLUG4LCU AWLUG4LCU 1637 +palermoc MACH_PALERMOC PALERMOC 1638 omap_ldp MACH_OMAP_LDP OMAP_LDP 1639 +ip500 MACH_IP500 IP500 1640 +ase2 MACH_ASE2 ASE2 1642 +mx35evb MACH_MX35EVB MX35EVB 1643 +aml_m8050 MACH_AML_M8050 AML_M8050 1644 mx35_3ds MACH_MX35_3DS MX35_3DS 1645 +mars MACH_MARS MARS 1646 neuros_osd2 MACH_NEUROS_OSD2 NEUROS_OSD2 1647 +badger MACH_BADGER BADGER 1648 trizeps4wl MACH_TRIZEPS4WL TRIZEPS4WL 1649 +trizeps5 MACH_TRIZEPS5 TRIZEPS5 1650 +marlin MACH_MARLIN MARLIN 1651 ts78xx MACH_TS78XX TS78XX 1652 +hpipaq214 MACH_HPIPAQ214 HPIPAQ214 1653 +at572d940dcm MACH_AT572D940DCM AT572D940DCM 1654 +ne1board MACH_NE1BOARD NE1BOARD 1655 +zante MACH_ZANTE ZANTE 1656 sffsdr MACH_SFFSDR SFFSDR 1657 +tw2662 MACH_TW2662 TW2662 1658 +vf10xx MACH_VF10XX VF10XX 1659 +zoran43xx MACH_ZORAN43XX ZORAN43XX 1660 +sonix926 MACH_SONIX926 SONIX926 1661 +celestialsemi MACH_CELESTIALSEMI CELESTIALSEMI 1662 +cc9m2443js MACH_CC9M2443JS CC9M2443JS 1663 +tw5334 MACH_TW5334 TW5334 1664 +omap_htcartemis MACH_HTCARTEMIS HTCARTEMIS 1665 +nal_hlite MACH_NAL_HLITE NAL_HLITE 1666 +htcvogue MACH_HTCVOGUE HTCVOGUE 1667 +smartweb MACH_SMARTWEB SMARTWEB 1668 +mv86xx MACH_MV86XX MV86XX 1669 +mv87xx MACH_MV87XX MV87XX 1670 +songyoungho MACH_SONGYOUNGHO SONGYOUNGHO 1671 +younghotema MACH_YOUNGHOTEMA YOUNGHOTEMA 1672 pcm037 MACH_PCM037 PCM037 1673 +mmvp MACH_MMVP MMVP 1674 +mmap MACH_MMAP MMAP 1675 +ptid2410 MACH_PTID2410 PTID2410 1676 +james_926 MACH_JAMES_926 JAMES_926 1677 +fm6000 MACH_FM6000 FM6000 1678 db88f6281_bp MACH_DB88F6281_BP DB88F6281_BP 1680 rd88f6192_nas MACH_RD88F6192_NAS RD88F6192_NAS 1681 rd88f6281 MACH_RD88F6281 RD88F6281 1682 db78x00_bp MACH_DB78X00_BP DB78X00_BP 1683 smdk2416 MACH_SMDK2416 SMDK2416 1685 +oce_spider_si MACH_OCE_SPIDER_SI OCE_SPIDER_SI 1686 +oce_spider_sk MACH_OCE_SPIDER_SK OCE_SPIDER_SK 1687 +rovern6 MACH_ROVERN6 ROVERN6 1688 +pelco_evolution MACH_PELCO_EVOLUTION PELCO_EVOLUTION 1689 wbd111 MACH_WBD111 WBD111 1690 +elaracpe MACH_ELARACPE ELARACPE 1691 +mabv3 MACH_MABV3 MABV3 1692 mv2120 MACH_MV2120 MV2120 1693 +csb737 MACH_CSB737 CSB737 1695 mx51_3ds MACH_MX51_3DS MX51_3DS 1696 +g900 MACH_G900 G900 1697 +apf27 MACH_APF27 APF27 1698 +ggus2000 MACH_GGUS2000 GGUS2000 1699 +omap_2430_mimic MACH_OMAP_2430_MIMIC OMAP_2430_MIMIC 1700 imx27lite MACH_IMX27LITE IMX27LITE 1701 +almex MACH_ALMEX ALMEX 1702 +control MACH_CONTROL CONTROL 1703 +mba2410 MACH_MBA2410 MBA2410 1704 +volcano MACH_VOLCANO VOLCANO 1705 +zenith MACH_ZENITH ZENITH 1706 +muchip MACH_MUCHIP MUCHIP 1707 +magellan MACH_MAGELLAN MAGELLAN 1708 usb_a9260 MACH_USB_A9260 USB_A9260 1709 usb_a9263 MACH_USB_A9263 USB_A9263 1710 qil_a9260 MACH_QIL_A9260 QIL_A9260 1711 +cme9210 MACH_CME9210 CME9210 1712 +hczh4 MACH_HCZH4 HCZH4 1713 +spearbasic MACH_SPEARBASIC SPEARBASIC 1714 +dep2440 MACH_DEP2440 DEP2440 1715 +hdl_gxr MACH_HDL_GXR HDL_GXR 1716 +hdl_gt MACH_HDL_GT HDL_GT 1717 +hdl_4g MACH_HDL_4G HDL_4G 1718 +s3c6000 MACH_S3C6000 S3C6000 1719 +mmsp2_mdk MACH_MMSP2_MDK MMSP2_MDK 1720 +mpx220 MACH_MPX220 MPX220 1721 kzm_arm11_01 MACH_KZM_ARM11_01 KZM_ARM11_01 1722 +htc_polaris MACH_HTC_POLARIS HTC_POLARIS 1723 +htc_kaiser MACH_HTC_KAISER HTC_KAISER 1724 +lg_ks20 MACH_LG_KS20 LG_KS20 1725 +hhgps MACH_HHGPS HHGPS 1726 nokia_n810_wimax MACH_NOKIA_N810_WIMAX NOKIA_N810_WIMAX 1727 +insight MACH_INSIGHT INSIGHT 1728 sapphire MACH_SAPPHIRE SAPPHIRE 1729 +csb637xo MACH_CSB637XO CSB637XO 1730 +evisiong MACH_EVISIONG EVISIONG 1731 stmp37xx MACH_STMP37XX STMP37XX 1732 stmp378x MACH_STMP378X STMP378X 1733 +tnt MACH_TNT TNT 1734 +tbxt MACH_TBXT TBXT 1735 +playmate MACH_PLAYMATE PLAYMATE 1736 +pns10 MACH_PNS10 PNS10 1737 +eznavi MACH_EZNAVI EZNAVI 1738 +ps4000 MACH_PS4000 PS4000 1739 ezx_a780 MACH_EZX_A780 EZX_A780 1740 ezx_e680 MACH_EZX_E680 EZX_E680 1741 ezx_a1200 MACH_EZX_A1200 EZX_A1200 1742 ezx_e6 MACH_EZX_E6 EZX_E6 1743 ezx_e2 MACH_EZX_E2 EZX_E2 1744 ezx_a910 MACH_EZX_A910 EZX_A910 1745 +cwmx31 MACH_CWMX31 CWMX31 1746 +sl2312 MACH_SL2312 SL2312 1747 +blenny MACH_BLENNY BLENNY 1748 +ds107 MACH_DS107 DS107 1749 +dsx07 MACH_DSX07 DSX07 1750 +picocom1 MACH_PICOCOM1 PICOCOM1 1751 +lynx_wolverine MACH_LYNX_WOLVERINE LYNX_WOLVERINE 1752 +ubisys_p9_sc19 MACH_UBISYS_P9_SC19 UBISYS_P9_SC19 1753 +kratos_low MACH_KRATOS_LOW KRATOS_LOW 1754 +m700 MACH_M700 M700 1755 edmini_v2 MACH_EDMINI_V2 EDMINI_V2 1756 zipit2 MACH_ZIPIT2 ZIPIT2 1757 +hslfemtocell MACH_HSLFEMTOCELL HSLFEMTOCELL 1758 +daintree_at91 MACH_DAINTREE_AT91 DAINTREE_AT91 1759 +sg560usb MACH_SG560USB SG560USB 1760 omap3_pandora MACH_OMAP3_PANDORA OMAP3_PANDORA 1761 +usr8200 MACH_USR8200 USR8200 1762 +s1s65k MACH_S1S65K S1S65K 1763 +s2s65a MACH_S2S65A S2S65A 1764 +icore MACH_ICORE ICORE 1765 mss2 MACH_MSS2 MSS2 1766 +belmont MACH_BELMONT BELMONT 1767 +asusp525 MACH_ASUSP525 ASUSP525 1768 lb88rc8480 MACH_LB88RC8480 LB88RC8480 1769 +hipxa MACH_HIPXA HIPXA 1770 mx25_3ds MACH_MX25_3DS MX25_3DS 1771 +m800 MACH_M800 M800 1772 omap3530_lv_som MACH_OMAP3530_LV_SOM OMAP3530_LV_SOM 1773 +prima_evb MACH_PRIMA_EVB PRIMA_EVB 1774 +mx31bt1 MACH_MX31BT1 MX31BT1 1775 +atlas4_evb MACH_ATLAS4_EVB ATLAS4_EVB 1776 +mx31cicada MACH_MX31CICADA MX31CICADA 1777 +mi424wr MACH_MI424WR MI424WR 1778 +axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779 +at572d940deb MACH_AT572D940DEB AT572D940DEB 1780 davinci_da830_evm MACH_DAVINCI_DA830_EVM DAVINCI_DA830_EVM 1781 +ep9302 MACH_EP9302 EP9302 1782 +at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783 +cybook3 MACH_CYBOOK3 CYBOOK3 1784 +wdg002 MACH_WDG002 WDG002 1785 +sg560adsl MACH_SG560ADSL SG560ADSL 1786 +nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787 dove_db MACH_DOVE_DB DOVE_DB 1788 +vandihud MACH_VANDIHUD VANDIHUD 1790 +magx_e8 MACH_MAGX_E8 MAGX_E8 1791 +magx_z6 MACH_MAGX_Z6 MAGX_Z6 1792 +magx_v8 MACH_MAGX_V8 MAGX_V8 1793 +magx_u9 MACH_MAGX_U9 MAGX_U9 1794 +toughcf08 MACH_TOUGHCF08 TOUGHCF08 1795 +zw4400 MACH_ZW4400 ZW4400 1796 +marat91 MACH_MARAT91 MARAT91 1797 overo MACH_OVERO OVERO 1798 at2440evb MACH_AT2440EVB AT2440EVB 1799 neocore926 MACH_NEOCORE926 NEOCORE926 1800 wnr854t MACH_WNR854T WNR854T 1801 +imx27 MACH_IMX27 IMX27 1802 +moose_db MACH_MOOSE_DB MOOSE_DB 1803 +fab4 MACH_FAB4 FAB4 1804 +htcdiamond MACH_HTCDIAMOND HTCDIAMOND 1805 +fiona MACH_FIONA FIONA 1806 +mxc30030_x MACH_MXC30030_X MXC30030_X 1807 +bmp1000 MACH_BMP1000 BMP1000 1808 +logi9200 MACH_LOGI9200 LOGI9200 1809 +tqma31 MACH_TQMA31 TQMA31 1810 +ccw9p9215js MACH_CCW9P9215JS CCW9P9215JS 1811 rd88f5181l_ge MACH_RD88F5181L_GE RD88F5181L_GE 1812 +sifmain MACH_SIFMAIN SIFMAIN 1813 +sam9_l9261 MACH_SAM9_L9261 SAM9_L9261 1814 +cc9m2443 MACH_CC9M2443 CC9M2443 1815 +xaria300 MACH_XARIA300 XARIA300 1816 +it9200 MACH_IT9200 IT9200 1817 rd88f5181l_fxo MACH_RD88F5181L_FXO RD88F5181L_FXO 1818 +kriss_sensor MACH_KRISS_SENSOR KRISS_SENSOR 1819 +pilz_pmi5 MACH_PILZ_PMI5 PILZ_PMI5 1820 +jade MACH_JADE JADE 1821 +ks8695_softplc MACH_KS8695_SOFTPLC KS8695_SOFTPLC 1822 +gprisc3 MACH_GPRISC3 GPRISC3 1823 stamp9g20 MACH_STAMP9G20 STAMP9G20 1824 +smdk6430 MACH_SMDK6430 SMDK6430 1825 smdkc100 MACH_SMDKC100 SMDKC100 1826 tavorevb MACH_TAVOREVB TAVOREVB 1827 saar MACH_SAAR SAAR 1828 +deister_eyecam MACH_DEISTER_EYECAM DEISTER_EYECAM 1829 at91sam9m10g45ek MACH_AT91SAM9M10G45EK AT91SAM9M10G45EK 1830 +linkstation_produo MACH_LINKSTATION_PRODUO LINKSTATION_PRODUO 1831 +hit_b0 MACH_HIT_B0 HIT_B0 1832 +adx_rmu MACH_ADX_RMU ADX_RMU 1833 +xg_cpe_main MACH_XG_CPE_MAIN XG_CPE_MAIN 1834 +edb9407a MACH_EDB9407A EDB9407A 1835 +dtb9608 MACH_DTB9608 DTB9608 1836 +em104v1 MACH_EM104V1 EM104V1 1837 +demo MACH_DEMO DEMO 1838 +logi9260 MACH_LOGI9260 LOGI9260 1839 +mx31_exm32 MACH_MX31_EXM32 MX31_EXM32 1840 usb_a9g20 MACH_USB_A9G20 USB_A9G20 1841 +picproje2008 MACH_PICPROJE2008 PICPROJE2008 1842 +cs_e9315 MACH_CS_E9315 CS_E9315 1843 +qil_a9g20 MACH_QIL_A9G20 QIL_A9G20 1844 +sha_pon020 MACH_SHA_PON020 SHA_PON020 1845 +nad MACH_NAD NAD 1846 +sbc35_a9260 MACH_SBC35_A9260 SBC35_A9260 1847 +sbc35_a9g20 MACH_SBC35_A9G20 SBC35_A9G20 1848 +davinci_beginning MACH_DAVINCI_BEGINNING DAVINCI_BEGINNING 1849 +uwc MACH_UWC UWC 1850 mxlads MACH_MXLADS MXLADS 1851 +htcnike MACH_HTCNIKE HTCNIKE 1852 +deister_pxa270 MACH_DEISTER_PXA270 DEISTER_PXA270 1853 +cme9210js MACH_CME9210JS CME9210JS 1854 +cc9p9360 MACH_CC9P9360 CC9P9360 1855 +mocha MACH_MOCHA MOCHA 1856 +wapd170ag MACH_WAPD170AG WAPD170AG 1857 linkstation_mini MACH_LINKSTATION_MINI LINKSTATION_MINI 1858 afeb9260 MACH_AFEB9260 AFEB9260 1859 +w90x900 MACH_W90X900 W90X900 1860 +w90x700 MACH_W90X700 W90X700 1861 +kt300ip MACH_KT300IP KT300IP 1862 +kt300ip_g20 MACH_KT300IP_G20 KT300IP_G20 1863 +srcm MACH_SRCM SRCM 1864 +wlnx_9260 MACH_WLNX_9260 WLNX_9260 1865 +openmoko_gta03 MACH_OPENMOKO_GTA03 OPENMOKO_GTA03 1866 +osprey2 MACH_OSPREY2 OSPREY2 1867 +kbio9260 MACH_KBIO9260 KBIO9260 1868 +ginza MACH_GINZA GINZA 1869 +a636n MACH_A636N A636N 1870 imx27ipcam MACH_IMX27IPCAM IMX27IPCAM 1871 +nemoc MACH_NEMOC NEMOC 1872 +geneva MACH_GENEVA GENEVA 1873 +htcpharos MACH_HTCPHAROS HTCPHAROS 1874 +neonc MACH_NEONC NEONC 1875 +nas7100 MACH_NAS7100 NAS7100 1876 +teuphone MACH_TEUPHONE TEUPHONE 1877 +annax_eth2 MACH_ANNAX_ETH2 ANNAX_ETH2 1878 +csb733 MACH_CSB733 CSB733 1879 +bk3 MACH_BK3 BK3 1880 +omap_em32 MACH_OMAP_EM32 OMAP_EM32 1881 +et9261cp MACH_ET9261CP ET9261CP 1882 +jasperc MACH_JASPERC JASPERC 1883 +issi_arm9 MACH_ISSI_ARM9 ISSI_ARM9 1884 +ued MACH_UED UED 1885 +esiblade MACH_ESIBLADE ESIBLADE 1886 +eye02 MACH_EYE02 EYE02 1887 +imx27kbd MACH_IMX27KBD IMX27KBD 1888 +kixvp435 MACH_KIXVP435 KIXVP435 1890 +kixnp435 MACH_KIXNP435 KIXNP435 1891 +africa MACH_AFRICA AFRICA 1892 +nh233 MACH_NH233 NH233 1893 rd88f6183ap_ge MACH_RD88F6183AP_GE RD88F6183AP_GE 1894 +bcm4760 MACH_BCM4760 BCM4760 1895 +eddy_v2 MACH_EDDY_V2 EDDY_V2 1896 realview_pba8 MACH_REALVIEW_PBA8 REALVIEW_PBA8 1897 +hid_a7 MACH_HID_A7 HID_A7 1898 +hero MACH_HERO HERO 1899 +omap_poseidon MACH_OMAP_POSEIDON OMAP_POSEIDON 1900 realview_pbx MACH_REALVIEW_PBX REALVIEW_PBX 1901 micro9s MACH_MICRO9S MICRO9S 1902 +mako MACH_MAKO MAKO 1903 +xdaflame MACH_XDAFLAME XDAFLAME 1904 +phidget_sbc2 MACH_PHIDGET_SBC2 PHIDGET_SBC2 1905 +limestone MACH_LIMESTONE LIMESTONE 1906 +iprobe_c32 MACH_IPROBE_C32 IPROBE_C32 1907 rut100 MACH_RUT100 RUT100 1908 +asusp535 MACH_ASUSP535 ASUSP535 1909 +htcraphael MACH_HTCRAPHAEL HTCRAPHAEL 1910 +sygdg1 MACH_SYGDG1 SYGDG1 1911 +sygdg2 MACH_SYGDG2 SYGDG2 1912 +seoul MACH_SEOUL SEOUL 1913 +salerno MACH_SALERNO SALERNO 1914 +ucn_s3c64xx MACH_UCN_S3C64XX UCN_S3C64XX 1915 +msm7201a MACH_MSM7201A MSM7201A 1916 +lpr1 MACH_LPR1 LPR1 1917 +armadillo500fx MACH_ARMADILLO500FX ARMADILLO500FX 1918 g3evm MACH_G3EVM G3EVM 1919 +z3_dm355 MACH_Z3_DM355 Z3_DM355 1920 w90p910evb MACH_W90P910EVB W90P910EVB 1921 +w90p920evb MACH_W90P920EVB W90P920EVB 1922 w90p950evb MACH_W90P950EVB W90P950EVB 1923 w90n960evb MACH_W90N960EVB W90N960EVB 1924 +camhd MACH_CAMHD CAMHD 1925 +mvc100 MACH_MVC100 MVC100 1926 +electrum_200 MACH_ELECTRUM_200 ELECTRUM_200 1927 +htcjade MACH_HTCJADE HTCJADE 1928 +memphis MACH_MEMPHIS MEMPHIS 1929 +imx27sbc MACH_IMX27SBC IMX27SBC 1930 +lextar MACH_LEXTAR LEXTAR 1931 mv88f6281gtw_ge MACH_MV88F6281GTW_GE MV88F6281GTW_GE 1932 ncp MACH_NCP NCP 1933 +z32an_series MACH_Z32AN Z32AN 1934 +tmq_capd MACH_TMQ_CAPD TMQ_CAPD 1935 +omap3_wl MACH_OMAP3_WL OMAP3_WL 1936 +chumby MACH_CHUMBY CHUMBY 1937 +atsarm9 MACH_ATSARM9 ATSARM9 1938 davinci_dm365_evm MACH_DAVINCI_DM365_EVM DAVINCI_DM365_EVM 1939 +bahamas MACH_BAHAMAS BAHAMAS 1940 +das MACH_DAS DAS 1941 +minidas MACH_MINIDAS MINIDAS 1942 +vk1000 MACH_VK1000 VK1000 1943 centro MACH_CENTRO CENTRO 1944 +ctera_2bay MACH_CTERA_2BAY CTERA_2BAY 1945 +edgeconnect MACH_EDGECONNECT EDGECONNECT 1946 +nd27000 MACH_ND27000 ND27000 1947 +cobra MACH_GEMALTO_COBRA GEMALTO_COBRA 1948 +ingelabs_comet MACH_INGELABS_COMET INGELABS_COMET 1949 +pollux_wiz MACH_POLLUX_WIZ POLLUX_WIZ 1950 +blackstone MACH_BLACKSTONE BLACKSTONE 1951 +topaz MACH_TOPAZ TOPAZ 1952 +aixle MACH_AIXLE AIXLE 1953 +mw998 MACH_MW998 MW998 1954 nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955 +vsc5605ev MACH_VSC5605EV VSC5605EV 1956 +nt98700dk MACH_NT98700DK NT98700DK 1957 +icontact MACH_ICONTACT ICONTACT 1958 +swarco_frcpu MACH_SWARCO_FRCPU SWARCO_FRCPU 1959 +swarco_scpu MACH_SWARCO_SCPU SWARCO_SCPU 1960 +bbox_p16 MACH_BBOX_P16 BBOX_P16 1961 +bstd MACH_BSTD BSTD 1962 +sbc2440ii MACH_SBC2440II SBC2440II 1963 +pcm034 MACH_PCM034 PCM034 1964 +neso MACH_NESO NESO 1965 +wlnx_9g20 MACH_WLNX_9G20 WLNX_9G20 1966 omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967 +totemnova MACH_TOTEMNOVA TOTEMNOVA 1968 +c5000 MACH_C5000 C5000 1969 +unipo_at91sam9263 MACH_UNIPO_AT91SAM9263 UNIPO_AT91SAM9263 1970 +ethernut5 MACH_ETHERNUT5 ETHERNUT5 1971 +arm11 MACH_ARM11 ARM11 1972 cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 +cpupxa255 MACH_CPUPXA255 CPUPXA255 1974 eukrea_cpuimx27 MACH_EUKREA_CPUIMX27 EUKREA_CPUIMX27 1975 +cheflux MACH_CHEFLUX CHEFLUX 1976 +eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977 +opcotec MACH_OPCOTEC OPCOTEC 1978 +yt MACH_YT YT 1979 +motoq MACH_MOTOQ MOTOQ 1980 +bsb1 MACH_BSB1 BSB1 1981 acs5k MACH_ACS5K ACS5K 1982 +milan MACH_MILAN MILAN 1983 +quartzv2 MACH_QUARTZV2 QUARTZV2 1984 +rsvp MACH_RSVP RSVP 1985 +rmp200 MACH_RMP200 RMP200 1986 snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987 dsm320 MACH_DSM320 DSM320 1988 +adsgcm MACH_ADSGCM ADSGCM 1989 +ase2_400 MACH_ASE2_400 ASE2_400 1990 +pizza MACH_PIZZA PIZZA 1991 +spot_ngpl MACH_SPOT_NGPL SPOT_NGPL 1992 +armata MACH_ARMATA ARMATA 1993 exeda MACH_EXEDA EXEDA 1994 +mx31sf005 MACH_MX31SF005 MX31SF005 1995 +f5d8231_4_v2 MACH_F5D8231_4_V2 F5D8231_4_V2 1996 +q2440 MACH_Q2440 Q2440 1997 +qq2440 MACH_QQ2440 QQ2440 1998 mini2440 MACH_MINI2440 MINI2440 1999 colibri300 MACH_COLIBRI300 COLIBRI300 2000 +jades MACH_JADES JADES 2001 +spark MACH_SPARK SPARK 2002 +benzina MACH_BENZINA BENZINA 2003 +blaze MACH_BLAZE BLAZE 2004 linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005 +htckovsky MACH_HTCKOVSKY HTCKOVSKY 2006 +sony_prs505 MACH_SONY_PRS505 SONY_PRS505 2007 +hanlin_v3 MACH_HANLIN_V3 HANLIN_V3 2008 +sapphira MACH_SAPPHIRA SAPPHIRA 2009 +dack_sda_01 MACH_DACK_SDA_01 DACK_SDA_01 2010 +armbox MACH_ARMBOX ARMBOX 2011 +harris_rvp MACH_HARRIS_RVP HARRIS_RVP 2012 +ribaldo MACH_RIBALDO RIBALDO 2013 +agora MACH_AGORA AGORA 2014 +omap3_mini MACH_OMAP3_MINI OMAP3_MINI 2015 +a9sam6432_b MACH_A9SAM6432_B A9SAM6432_B 2016 +usg2410 MACH_USG2410 USG2410 2017 +pc72052_i10_revb MACH_PC72052_I10_REVB PC72052_I10_REVB 2018 +mx35_exm32 MACH_MX35_EXM32 MX35_EXM32 2019 +topas910 MACH_TOPAS910 TOPAS910 2020 +hyena MACH_HYENA HYENA 2021 +pospax MACH_POSPAX POSPAX 2022 +hdl_gx MACH_HDL_GX HDL_GX 2023 +ctera_4bay MACH_CTERA_4BAY CTERA_4BAY 2024 +ctera_plug_c MACH_CTERA_PLUG_C CTERA_PLUG_C 2025 +crwea_plug_i MACH_CRWEA_PLUG_I CRWEA_PLUG_I 2026 +egauge2 MACH_EGAUGE2 EGAUGE2 2027 +didj MACH_DIDJ DIDJ 2028 +m_s3c2443 MACH_MEISTER MEISTER 2029 +htcblackstone MACH_HTCBLACKSTONE HTCBLACKSTONE 2030 cpuat9g20 MACH_CPUAT9G20 CPUAT9G20 2031 smdk6440 MACH_SMDK6440 SMDK6440 2032 +omap_35xx_mvp MACH_OMAP_35XX_MVP OMAP_35XX_MVP 2033 +ctera_plug_i MACH_CTERA_PLUG_I CTERA_PLUG_I 2034 +pvg610_100 MACH_PVG610 PVG610 2035 +hprw6815 MACH_HPRW6815 HPRW6815 2036 +omap3_oswald MACH_OMAP3_OSWALD OMAP3_OSWALD 2037 nas4220b MACH_NAS4220B NAS4220B 2038 +htcraphael_cdma MACH_HTCRAPHAEL_CDMA HTCRAPHAEL_CDMA 2039 +htcdiamond_cdma MACH_HTCDIAMOND_CDMA HTCDIAMOND_CDMA 2040 +scaler MACH_SCALER SCALER 2041 zylonite2 MACH_ZYLONITE2 ZYLONITE2 2042 aspenite MACH_ASPENITE ASPENITE 2043 +teton MACH_TETON TETON 2044 ttc_dkb MACH_TTC_DKB TTC_DKB 2045 +bishop2 MACH_BISHOP2 BISHOP2 2046 +ippv5 MACH_IPPV5 IPPV5 2047 +farm926 MACH_FARM926 FARM926 2048 +mmccpu MACH_MMCCPU MMCCPU 2049 +sgmsfl MACH_SGMSFL SGMSFL 2050 +tt8000 MACH_TT8000 TT8000 2051 +zrn4300lp MACH_ZRN4300LP ZRN4300LP 2052 +mptc MACH_MPTC MPTC 2053 +h6051 MACH_H6051 H6051 2054 +pvg610_101 MACH_PVG610_101 PVG610_101 2055 +stamp9261_pc_evb MACH_STAMP9261_PC_EVB STAMP9261_PC_EVB 2056 +pelco_odysseus MACH_PELCO_ODYSSEUS PELCO_ODYSSEUS 2057 +tny_a9260 MACH_TNY_A9260 TNY_A9260 2058 +tny_a9g20 MACH_TNY_A9G20 TNY_A9G20 2059 +aesop_mp2530f MACH_AESOP_MP2530F AESOP_MP2530F 2060 +dx900 MACH_DX900 DX900 2061 +cpodc2 MACH_CPODC2 CPODC2 2062 +tilt_8925 MACH_TILT_8925 TILT_8925 2063 +davinci_dm357_evm MACH_DAVINCI_DM357_EVM DAVINCI_DM357_EVM 2064 +swordfish MACH_SWORDFISH SWORDFISH 2065 +corvus MACH_CORVUS CORVUS 2066 +taurus MACH_TAURUS TAURUS 2067 +axm MACH_AXM AXM 2068 +axc MACH_AXC AXC 2069 +baby MACH_BABY BABY 2070 +mp200 MACH_MP200 MP200 2071 pcm043 MACH_PCM043 PCM043 2072 +hanlin_v3c MACH_HANLIN_V3C HANLIN_V3C 2073 +kbk9g20 MACH_KBK9G20 KBK9G20 2074 +adsturbog5 MACH_ADSTURBOG5 ADSTURBOG5 2075 +avenger_lite1 MACH_AVENGER_LITE1 AVENGER_LITE1 2076 +suc82x MACH_SUC SUC 2077 +at91sam7s256 MACH_AT91SAM7S256 AT91SAM7S256 2078 +mendoza MACH_MENDOZA MENDOZA 2079 +kira MACH_KIRA KIRA 2080 +mx1hbm MACH_MX1HBM MX1HBM 2081 +quatro43xx MACH_QUATRO43XX QUATRO43XX 2082 +quatro4230 MACH_QUATRO4230 QUATRO4230 2083 +nsb400 MACH_NSB400 NSB400 2084 +drp255 MACH_DRP255 DRP255 2085 +thoth MACH_THOTH THOTH 2086 +firestone MACH_FIRESTONE FIRESTONE 2087 +asusp750 MACH_ASUSP750 ASUSP750 2088 +ctera_dl MACH_CTERA_DL CTERA_DL 2089 +socr MACH_SOCR SOCR 2090 +htcoxygen MACH_HTCOXYGEN HTCOXYGEN 2091 +heroc MACH_HEROC HEROC 2092 +zeno6800 MACH_ZENO6800 ZENO6800 2093 +sc2mcs MACH_SC2MCS SC2MCS 2094 +gene100 MACH_GENE100 GENE100 2095 +as353x MACH_AS353X AS353X 2096 sheevaplug MACH_SHEEVAPLUG SHEEVAPLUG 2097 +at91sam9g20 MACH_AT91SAM9G20 AT91SAM9G20 2098 +mv88f6192gtw_fe MACH_MV88F6192GTW_FE MV88F6192GTW_FE 2099 +cc9200 MACH_CC9200 CC9200 2100 +sm9200 MACH_SM9200 SM9200 2101 +tp9200 MACH_TP9200 TP9200 2102 +snapperdv MACH_SNAPPERDV SNAPPERDV 2103 avengers_lite MACH_AVENGERS_LITE AVENGERS_LITE 2104 +avengers_lite1 MACH_AVENGERS_LITE1 AVENGERS_LITE1 2105 +omap3axon MACH_OMAP3AXON OMAP3AXON 2106 +ma8xx MACH_MA8XX MA8XX 2107 +mp201ek MACH_MP201EK MP201EK 2108 +davinci_tux MACH_DAVINCI_TUX DAVINCI_TUX 2109 +mpa1600 MACH_MPA1600 MPA1600 2110 +pelco_troy MACH_PELCO_TROY PELCO_TROY 2111 +nsb667 MACH_NSB667 NSB667 2112 +rovers5_4mpix MACH_ROVERS5_4MPIX ROVERS5_4MPIX 2113 +twocom MACH_TWOCOM TWOCOM 2114 +ubisys_p9_rcu3r2 MACH_UBISYS_P9_RCU3R2 UBISYS_P9_RCU3R2 2115 +hero_espresso MACH_HERO_ESPRESSO HERO_ESPRESSO 2116 +afeusb MACH_AFEUSB AFEUSB 2117 +t830 MACH_T830 T830 2118 +spd8020_cc MACH_SPD8020_CC SPD8020_CC 2119 +om_3d7k MACH_OM_3D7K OM_3D7K 2120 +picocom2 MACH_PICOCOM2 PICOCOM2 2121 +uwg4mx27 MACH_UWG4MX27 UWG4MX27 2122 +uwg4mx31 MACH_UWG4MX31 UWG4MX31 2123 +cherry MACH_CHERRY CHERRY 2124 mx51_babbage MACH_MX51_BABBAGE MX51_BABBAGE 2125 +s3c2440turkiye MACH_S3C2440TURKIYE S3C2440TURKIYE 2126 tx37 MACH_TX37 TX37 2127 +sbc2800_9g20 MACH_SBC2800_9G20 SBC2800_9G20 2128 +benzglb MACH_BENZGLB BENZGLB 2129 +benztd MACH_BENZTD BENZTD 2130 +cartesio_plus MACH_CARTESIO_PLUS CARTESIO_PLUS 2131 +solrad_g20 MACH_SOLRAD_G20 SOLRAD_G20 2132 +mx27wallace MACH_MX27WALLACE MX27WALLACE 2133 +fmzwebmodul MACH_FMZWEBMODUL FMZWEBMODUL 2134 rd78x00_masa MACH_RD78X00_MASA RD78X00_MASA 2135 +smallogger MACH_SMALLOGGER SMALLOGGER 2136 +ccw9p9215 MACH_CCW9P9215 CCW9P9215 2137 dm355_leopard MACH_DM355_LEOPARD DM355_LEOPARD 2138 ts219 MACH_TS219 TS219 2139 +tny_a9263 MACH_TNY_A9263 TNY_A9263 2140 +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 +lal43 MACH_LAL43 LAL43 2181 +htcraphael_cdma500 MACH_HTCRAPHAEL_CDMA500 HTCRAPHAEL_CDMA500 2182 anw6410 MACH_ANW6410 ANW6410 2183 +htcprophet MACH_HTCPROPHET HTCPROPHET 2185 +cfa_10022 MACH_CFA_10022 CFA_10022 2186 imx27_visstrim_m10 MACH_IMX27_VISSTRIM_M10 IMX27_VISSTRIM_M10 2187 +px2imx27 MACH_PX2IMX27 PX2IMX27 2188 +stm3210e_eval MACH_STM3210E_EVAL STM3210E_EVAL 2189 +dvs10 MACH_DVS10 DVS10 2190 portuxg20 MACH_PORTUXG20 PORTUXG20 2191 +arm_spv MACH_ARM_SPV ARM_SPV 2192 smdkc110 MACH_SMDKC110 SMDKC110 2193 +cabespresso MACH_CABESPRESSO CABESPRESSO 2194 +hmc800 MACH_HMC800 HMC800 2195 +sholes MACH_SHOLES SHOLES 2196 +btmxc31 MACH_BTMXC31 BTMXC31 2197 +dt501 MACH_DT501 DT501 2198 +ktx MACH_KTX KTX 2199 omap3517evm MACH_OMAP3517EVM OMAP3517EVM 2200 netspace_v2 MACH_NETSPACE_V2 NETSPACE_V2 2201 netspace_max_v2 MACH_NETSPACE_MAX_V2 NETSPACE_MAX_V2 2202 d2net_v2 MACH_D2NET_V2 D2NET_V2 2203 net2big_v2 MACH_NET2BIG_V2 NET2BIG_V2 2204 +net4big_v2 MACH_NET4BIG_V2 NET4BIG_V2 2205 net5big_v2 MACH_NET5BIG_V2 NET5BIG_V2 2206 +endb2443 MACH_ENDB2443 ENDB2443 2207 inetspace_v2 MACH_INETSPACE_V2 INETSPACE_V2 2208 +tros MACH_TROS TROS 2209 +pelco_homer MACH_PELCO_HOMER PELCO_HOMER 2210 +ofsp8 MACH_OFSP8 OFSP8 2211 at91sam9g45ekes MACH_AT91SAM9G45EKES AT91SAM9G45EKES 2212 +guf_cupid MACH_GUF_CUPID GUF_CUPID 2213 +eab1r MACH_EAB1R EAB1R 2214 +desirec MACH_DESIREC DESIREC 2215 +cordoba MACH_CORDOBA CORDOBA 2216 +irvine MACH_IRVINE IRVINE 2217 +sff772 MACH_SFF772 SFF772 2218 +pelco_milano MACH_PELCO_MILANO PELCO_MILANO 2219 pc7302 MACH_PC7302 PC7302 2220 +bip6000 MACH_BIP6000 BIP6000 2221 +silvermoon MACH_SILVERMOON SILVERMOON 2222 +vc0830 MACH_VC0830 VC0830 2223 +dt430 MACH_DT430 DT430 2224 +ji42pf MACH_JI42PF JI42PF 2225 +gnet_ksm MACH_GNET_KSM GNET_KSM 2226 +gnet_sgm MACH_GNET_SGM GNET_SGM 2227 +gnet_sgr MACH_GNET_SGR GNET_SGR 2228 +omap3_icetekevm MACH_OMAP3_ICETEKEVM OMAP3_ICETEKEVM 2229 +pnp MACH_PNP PNP 2230 +ctera_2bay_k MACH_CTERA_2BAY_K CTERA_2BAY_K 2231 +ctera_2bay_u MACH_CTERA_2BAY_U CTERA_2BAY_U 2232 +sas_c MACH_SAS_C SAS_C 2233 +vma2315 MACH_VMA2315 VMA2315 2234 +vcs MACH_VCS VCS 2235 spear600 MACH_SPEAR600 SPEAR600 2236 spear300 MACH_SPEAR300 SPEAR300 2237 +spear1300 MACH_SPEAR1300 SPEAR1300 2238 lilly1131 MACH_LILLY1131 LILLY1131 2239 +arvoo_ax301 MACH_ARVOO_AX301 ARVOO_AX301 2240 +mapphone MACH_MAPPHONE MAPPHONE 2241 +legend MACH_LEGEND LEGEND 2242 +salsa MACH_SALSA SALSA 2243 +lounge MACH_LOUNGE LOUNGE 2244 +vision MACH_VISION VISION 2245 +vmb20 MACH_VMB20 VMB20 2246 +hy2410 MACH_HY2410 HY2410 2247 +hy9315 MACH_HY9315 HY9315 2248 +bullwinkle MACH_BULLWINKLE BULLWINKLE 2249 +arm_ultimator2 MACH_ARM_ULTIMATOR2 ARM_ULTIMATOR2 2250 +vs_v210 MACH_VS_V210 VS_V210 2252 +vs_v212 MACH_VS_V212 VS_V212 2253 hmt MACH_HMT HMT 2254 +km_kirkwood MACH_KM_KIRKWOOD KM_KIRKWOOD 2255 +vesper MACH_VESPER VESPER 2256 +str9 MACH_STR9 STR9 2257 +omap3_wl_ff MACH_OMAP3_WL_FF OMAP3_WL_FF 2258 +simcom MACH_SIMCOM SIMCOM 2259 +mcwebio MACH_MCWEBIO MCWEBIO 2260 +omap3_phrazer MACH_OMAP3_PHRAZER OMAP3_PHRAZER 2261 +darwin MACH_DARWIN DARWIN 2262 +oratiscomu MACH_ORATISCOMU ORATISCOMU 2263 +rtsbc20 MACH_RTSBC20 RTSBC20 2264 +sgh_i780 MACH_I780 I780 2265 +gemini324 MACH_GEMINI324 GEMINI324 2266 +oratislan MACH_ORATISLAN ORATISLAN 2267 +oratisalog MACH_ORATISALOG ORATISALOG 2268 +oratismadi MACH_ORATISMADI ORATISMADI 2269 +oratisot16 MACH_ORATISOT16 ORATISOT16 2270 +oratisdesk MACH_ORATISDESK ORATISDESK 2271 vexpress MACH_VEXPRESS VEXPRESS 2272 +sintexo MACH_SINTEXO SINTEXO 2273 +cm3389 MACH_CM3389 CM3389 2274 +omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275 +sgh_i900 MACH_SGH_I900 SGH_I900 2276 +bst100 MACH_BST100 BST100 2277 +passion MACH_PASSION PASSION 2278 +indesign_at91sam MACH_INDESIGN_AT91SAM INDESIGN_AT91SAM 2279 +c4_badger MACH_C4_BADGER C4_BADGER 2280 +c4_viper MACH_C4_VIPER C4_VIPER 2281 d2net MACH_D2NET D2NET 2282 bigdisk MACH_BIGDISK BIGDISK 2283 +notalvision MACH_NOTALVISION NOTALVISION 2284 +omap3_kboc MACH_OMAP3_KBOC OMAP3_KBOC 2285 +cyclone MACH_CYCLONE CYCLONE 2286 +ninja MACH_NINJA NINJA 2287 at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288 bcmring MACH_BCMRING BCMRING 2289 +resol_dl2 MACH_RESOL_DL2 RESOL_DL2 2290 +ifosw MACH_IFOSW IFOSW 2291 +htcrhodium MACH_HTCRHODIUM HTCRHODIUM 2292 +htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293 +matrix504 MACH_MATRIX504 MATRIX504 2294 +mrfsa MACH_MRFSA MRFSA 2295 +sc_p270 MACH_SC_P270 SC_P270 2296 +atlas5_evb MACH_ATLAS5_EVB ATLAS5_EVB 2297 +pelco_lobox MACH_PELCO_LOBOX PELCO_LOBOX 2298 +dilax_pcu200 MACH_DILAX_PCU200 DILAX_PCU200 2299 +leonardo MACH_LEONARDO LEONARDO 2300 +zoran_approach7 MACH_ZORAN_APPROACH7 ZORAN_APPROACH7 2301 dp6xx MACH_DP6XX DP6XX 2302 +bcm2153_vesper MACH_BCM2153_VESPER BCM2153_VESPER 2303 mahimahi MACH_MAHIMAHI MAHIMAHI 2304 +clickc MACH_CLICKC CLICKC 2305 +zb_gateway MACH_ZB_GATEWAY ZB_GATEWAY 2306 +tazcard MACH_TAZCARD TAZCARD 2307 +tazdev MACH_TAZDEV TAZDEV 2308 +annax_cb_arm MACH_ANNAX_CB_ARM ANNAX_CB_ARM 2309 +annax_dm3 MACH_ANNAX_DM3 ANNAX_DM3 2310 +cerebric MACH_CEREBRIC CEREBRIC 2311 +orca MACH_ORCA ORCA 2312 +pc9260 MACH_PC9260 PC9260 2313 +ems285a MACH_EMS285A EMS285A 2314 +gec2410 MACH_GEC2410 GEC2410 2315 +gec2440 MACH_GEC2440 GEC2440 2316 +mw903 MACH_ARCH_MW903 ARCH_MW903 2317 +mw2440 MACH_MW2440 MW2440 2318 +ecac2378 MACH_ECAC2378 ECAC2378 2319 +tazkiosk MACH_TAZKIOSK TAZKIOSK 2320 +whiterabbit_mch MACH_WHITERABBIT_MCH WHITERABBIT_MCH 2321 +sbox9263 MACH_SBOX9263 SBOX9263 2322 smdk6442 MACH_SMDK6442 SMDK6442 2324 openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325 +incredible MACH_INCREDIBLE INCREDIBLE 2326 +incrediblec MACH_INCREDIBLEC INCREDIBLEC 2327 +heroct MACH_HEROCT HEROCT 2328 +mmnet1000 MACH_MMNET1000 MMNET1000 2329 devkit8000 MACH_DEVKIT8000 DEVKIT8000 2330 +devkit9000 MACH_DEVKIT9000 DEVKIT9000 2331 +mx31txtr MACH_MX31TXTR MX31TXTR 2332 +u380 MACH_U380 U380 2333 +oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 +npcmx50 MACH_NPCMX50 NPCMX50 2335 mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336 +mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 +riom MACH_RIOM RIOM 2338 +comcas MACH_COMCAS COMCAS 2339 +wsi_mx27 MACH_WSI_MX27 WSI_MX27 2340 cm_t35 MACH_CM_T35 CM_T35 2341 net2big MACH_NET2BIG NET2BIG 2342 +motorola_a1600 MACH_MOTOROLA_A1600 MOTOROLA_A1600 2343 igep0020 MACH_IGEP0020 IGEP0020 2344 +igep0010 MACH_IGEP0010 IGEP0010 2345 +mv6281gtwge2 MACH_MV6281GTWGE2 MV6281GTWGE2 2346 +scat100 MACH_SCAT100 SCAT100 2347 +sanmina MACH_SANMINA SANMINA 2348 +momento MACH_MOMENTO MOMENTO 2349 +nuc9xx MACH_NUC9XX NUC9XX 2350 +nuc910evb MACH_NUC910EVB NUC910EVB 2351 +nuc920evb MACH_NUC920EVB NUC920EVB 2352 +nuc950evb MACH_NUC950EVB NUC950EVB 2353 +nuc945evb MACH_NUC945EVB NUC945EVB 2354 +nuc960evb MACH_NUC960EVB NUC960EVB 2355 nuc932evb MACH_NUC932EVB NUC932EVB 2356 +nuc900 MACH_NUC900 NUC900 2357 +sd1soc MACH_SD1SOC SD1SOC 2358 +ln2440bc MACH_LN2440BC LN2440BC 2359 +rsbc MACH_RSBC RSBC 2360 openrd_client MACH_OPENRD_CLIENT OPENRD_CLIENT 2361 +hpipaq11x MACH_HPIPAQ11X HPIPAQ11X 2362 +wayland MACH_WAYLAND WAYLAND 2363 +acnbsx102 MACH_ACNBSX102 ACNBSX102 2364 +hwat91 MACH_HWAT91 HWAT91 2365 +at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 +csb732 MACH_CSB732 CSB732 2367 u8500 MACH_U8500 U8500 2368 +huqiu MACH_HUQIU HUQIU 2369 mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370 +pmt1g MACH_PMT1G PMT1G 2371 +htcelf MACH_HTCELF HTCELF 2372 +armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 +armadillo440 MACH_ARMADILLO440 ARMADILLO440 2374 +u_chip_dual_arm MACH_U_CHIP_DUAL_ARM U_CHIP_DUAL_ARM 2375 +csr_bdb3 MACH_CSR_BDB3 CSR_BDB3 2376 +dolby_cat1018 MACH_DOLBY_CAT1018 DOLBY_CAT1018 2377 +hy9307 MACH_HY9307 HY9307 2378 +aspire_easystore MACH_A_ES A_ES 2379 +davinci_irif MACH_DAVINCI_IRIF DAVINCI_IRIF 2380 +agama9263 MACH_AGAMA9263 AGAMA9263 2381 marvell_jasper MACH_MARVELL_JASPER MARVELL_JASPER 2382 flint MACH_FLINT FLINT 2383 tavorevb3 MACH_TAVOREVB3 TAVOREVB3 2384 +sch_m490 MACH_SCH_M490 SCH_M490 2386 +rbl01 MACH_RBL01 RBL01 2387 +omnifi MACH_OMNIFI OMNIFI 2388 +otavalo MACH_OTAVALO OTAVALO 2389 +htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391 +htc_opal MACH_HTC_OPAL HTC_OPAL 2392 touchbook MACH_TOUCHBOOK TOUCHBOOK 2393 +latte MACH_LATTE LATTE 2394 +xa200 MACH_XA200 XA200 2395 +nimrod MACH_NIMROD NIMROD 2396 +cc9p9215_3g MACH_CC9P9215_3G CC9P9215_3G 2397 +cc9p9215_3gjs MACH_CC9P9215_3GJS CC9P9215_3GJS 2398 +tk71 MACH_TK71 TK71 2399 +comham3525 MACH_COMHAM3525 COMHAM3525 2400 +mx31erebus MACH_MX31EREBUS MX31EREBUS 2401 +mcardmx27 MACH_MCARDMX27 MCARDMX27 2402 +paradise MACH_PARADISE PARADISE 2403 +tide MACH_TIDE TIDE 2404 +wzl2440 MACH_WZL2440 WZL2440 2405 +sdrdemo MACH_SDRDEMO SDRDEMO 2406 +ethercan2 MACH_ETHERCAN2 ETHERCAN2 2407 +ecmimg20 MACH_ECMIMG20 ECMIMG20 2408 +omap_dragon MACH_OMAP_DRAGON OMAP_DRAGON 2409 +halo MACH_HALO HALO 2410 +huangshan MACH_HUANGSHAN HUANGSHAN 2411 +vl_ma2sc MACH_VL_MA2SC VL_MA2SC 2412 raumfeld_rc MACH_RAUMFELD_RC RAUMFELD_RC 2413 raumfeld_connector MACH_RAUMFELD_CONNECTOR RAUMFELD_CONNECTOR 2414 raumfeld_speaker MACH_RAUMFELD_SPEAKER RAUMFELD_SPEAKER 2415 +multibus_master MACH_MULTIBUS_MASTER MULTIBUS_MASTER 2416 +multibus_pbk MACH_MULTIBUS_PBK MULTIBUS_PBK 2417 tnetv107x MACH_TNETV107X TNETV107X 2418 +snake MACH_SNAKE SNAKE 2419 +cwmx27 MACH_CWMX27 CWMX27 2420 +sch_m480 MACH_SCH_M480 SCH_M480 2421 +platypus MACH_PLATYPUS PLATYPUS 2422 +pss2 MACH_PSS2 PSS2 2423 +davinci_apm150 MACH_DAVINCI_APM150 DAVINCI_APM150 2424 +str9100 MACH_STR9100 STR9100 2425 +net5big MACH_NET5BIG NET5BIG 2426 +seabed9263 MACH_SEABED9263 SEABED9263 2427 mx51_m2id MACH_MX51_M2ID MX51_M2ID 2428 +octvocplus_eb MACH_OCTVOCPLUS_EB OCTVOCPLUS_EB 2429 +klk_firefox MACH_KLK_FIREFOX KLK_FIREFOX 2430 +klk_wirma_module MACH_KLK_WIRMA_MODULE KLK_WIRMA_MODULE 2431 +klk_wirma_mmi MACH_KLK_WIRMA_MMI KLK_WIRMA_MMI 2432 +supersonic MACH_SUPERSONIC SUPERSONIC 2433 +liberty MACH_LIBERTY LIBERTY 2434 +mh355 MACH_MH355 MH355 2435 +pc7802 MACH_PC7802 PC7802 2436 +gnet_sgc MACH_GNET_SGC GNET_SGC 2437 +einstein15 MACH_EINSTEIN15 EINSTEIN15 2438 +cmpd MACH_CMPD CMPD 2439 +davinci_hase1 MACH_DAVINCI_HASE1 DAVINCI_HASE1 2440 +lgeincitephone MACH_LGEINCITEPHONE LGEINCITEPHONE 2441 +ea313x MACH_EA313X EA313X 2442 +fwbd_39064 MACH_FWBD_39064 FWBD_39064 2443 +fwbd_390128 MACH_FWBD_390128 FWBD_390128 2444 +pelco_moe MACH_PELCO_MOE PELCO_MOE 2445 +minimix27 MACH_MINIMIX27 MINIMIX27 2446 +omap3_thunder MACH_OMAP3_THUNDER OMAP3_THUNDER 2447 +passionc MACH_PASSIONC PASSIONC 2448 +mx27amata MACH_MX27AMATA MX27AMATA 2449 +bgat1 MACH_BGAT1 BGAT1 2450 +buzz MACH_BUZZ BUZZ 2451 +mb9g20 MACH_MB9G20 MB9G20 2452 +yushan MACH_YUSHAN YUSHAN 2453 +lizard MACH_LIZARD LIZARD 2454 +omap3polycom MACH_OMAP3POLYCOM OMAP3POLYCOM 2455 smdkv210 MACH_SMDKV210 SMDKV210 2456 +bravo MACH_BRAVO BRAVO 2457 +siogentoo1 MACH_SIOGENTOO1 SIOGENTOO1 2458 +siogentoo2 MACH_SIOGENTOO2 SIOGENTOO2 2459 +sm3k MACH_SM3K SM3K 2460 +acer_tempo_f900 MACH_ACER_TEMPO_F900 ACER_TEMPO_F900 2461 +glittertind MACH_GLITTERTIND GLITTERTIND 2463 omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464 omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465 +cybook2440 MACH_CYBOOK2440 CYBOOK2440 2466 +torino_s MACH_TORINO_S TORINO_S 2467 +havana MACH_HAVANA HAVANA 2468 +beaumont_11 MACH_BEAUMONT_11 BEAUMONT_11 2469 +vanguard MACH_VANGUARD VANGUARD 2470 +s5pc110_draco MACH_S5PC110_DRACO S5PC110_DRACO 2471 +cartesio_two MACH_CARTESIO_TWO CARTESIO_TWO 2472 +aster MACH_ASTER ASTER 2473 +voguesv210 MACH_VOGUESV210 VOGUESV210 2474 +acm500x MACH_ACM500X ACM500X 2475 +km9260 MACH_KM9260 KM9260 2476 +nideflexg1 MACH_NIDEFLEXG1 NIDEFLEXG1 2477 +ctera_plug_io MACH_CTERA_PLUG_IO CTERA_PLUG_IO 2478 smartq7 MACH_SMARTQ7 SMARTQ7 2479 +at91sam9g10ek2 MACH_AT91SAM9G10EK2 AT91SAM9G10EK2 2480 +asusp527 MACH_ASUSP527 ASUSP527 2481 +at91sam9g20mpm2 MACH_AT91SAM9G20MPM2 AT91SAM9G20MPM2 2482 +topasa900 MACH_TOPASA900 TOPASA900 2483 +electrum_100 MACH_ELECTRUM_100 ELECTRUM_100 2484 +mx51grb MACH_MX51GRB MX51GRB 2485 +xea300 MACH_XEA300 XEA300 2486 +htcstartrek MACH_HTCSTARTREK HTCSTARTREK 2487 +lima MACH_LIMA LIMA 2488 +csb740 MACH_CSB740 CSB740 2489 +usb_s8815 MACH_USB_S8815 USB_S8815 2490 watson_efm_plugin MACH_WATSON_EFM_PLUGIN WATSON_EFM_PLUGIN 2491 +milkyway MACH_MILKYWAY MILKYWAY 2492 g4evm MACH_G4EVM G4EVM 2493 +picomod6 MACH_PICOMOD6 PICOMOD6 2494 omapl138_hawkboard MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD 2495 +ip6000 MACH_IP6000 IP6000 2496 +ip6010 MACH_IP6010 IP6010 2497 +utm400 MACH_UTM400 UTM400 2498 +omap3_zybex MACH_OMAP3_ZYBEX OMAP3_ZYBEX 2499 +wireless_space MACH_WIRELESS_SPACE WIRELESS_SPACE 2500 +sx560 MACH_SX560 SX560 2501 ts41x MACH_TS41X TS41X 2502 +elphel10373 MACH_ELPHEL10373 ELPHEL10373 2503 +rhobot MACH_RHOBOT RHOBOT 2504 +mx51_refresh MACH_MX51_REFRESH MX51_REFRESH 2505 +ls9260 MACH_LS9260 LS9260 2506 +shank MACH_SHANK SHANK 2507 +qsd8x50_st1 MACH_QSD8X50_ST1 QSD8X50_ST1 2508 +at91sam9m10ekes MACH_AT91SAM9M10EKES AT91SAM9M10EKES 2509 +hiram MACH_HIRAM HIRAM 2510 phy3250 MACH_PHY3250 PHY3250 2511 +ea3250 MACH_EA3250 EA3250 2512 +fdi3250 MACH_FDI3250 FDI3250 2513 +at91sam9263nit MACH_AT91SAM9263NIT AT91SAM9263NIT 2515 +ccmx51 MACH_CCMX51 CCMX51 2516 +ccmx51js MACH_CCMX51JS CCMX51JS 2517 +ccwmx51 MACH_CCWMX51 CCWMX51 2518 +ccwmx51js MACH_CCWMX51JS CCWMX51JS 2519 mini6410 MACH_MINI6410 MINI6410 2520 +tiny6410 MACH_TINY6410 TINY6410 2521 +nano6410 MACH_NANO6410 NANO6410 2522 +at572d940hfnldb MACH_AT572D940HFNLDB AT572D940HFNLDB 2523 +htcleo MACH_HTCLEO HTCLEO 2524 +avp13 MACH_AVP13 AVP13 2525 +xxsvideod MACH_XXSVIDEOD XXSVIDEOD 2526 +vpnext MACH_VPNEXT VPNEXT 2527 +swarco_itc3 MACH_SWARCO_ITC3 SWARCO_ITC3 2528 tx51 MACH_TX51 TX51 2529 +dolby_cat1021 MACH_DOLBY_CAT1021 DOLBY_CAT1021 2530 mx28evk MACH_MX28EVK MX28EVK 2531 +phoenix260 MACH_PHOENIX260 PHOENIX260 2532 +uvaca_stork MACH_UVACA_STORK UVACA_STORK 2533 smartq5 MACH_SMARTQ5 SMARTQ5 2534 +all3078 MACH_ALL3078 ALL3078 2535 +ctera_2bay_ds MACH_CTERA_2BAY_DS CTERA_2BAY_DS 2536 +siogentoo3 MACH_SIOGENTOO3 SIOGENTOO3 2537 +epb5000 MACH_EPB5000 EPB5000 2538 +hy9263 MACH_HY9263 HY9263 2539 +acer_tempo_m900 MACH_ACER_TEMPO_M900 ACER_TEMPO_M900 2540 +acer_tempo_dx650 MACH_ACER_TEMPO_DX900 ACER_TEMPO_DX900 2541 +acer_tempo_x960 MACH_ACER_TEMPO_X960 ACER_TEMPO_X960 2542 +acer_eten_v900 MACH_ACER_ETEN_V900 ACER_ETEN_V900 2543 +acer_eten_x900 MACH_ACER_ETEN_X900 ACER_ETEN_X900 2544 +bonnell MACH_BONNELL BONNELL 2545 +oht_mx27 MACH_OHT_MX27 OHT_MX27 2546 +htcquartz MACH_HTCQUARTZ HTCQUARTZ 2547 davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548 +c3ax03 MACH_C3AX03 C3AX03 2549 mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 +esyx MACH_ESYX ESYX 2551 +dove_db2 MACH_DOVE_DB2 DOVE_DB2 2552 +bulldog MACH_BULLDOG BULLDOG 2553 +derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554 +bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555 +bcmring_evm MACH_BCMRING_EVM BCMRING_EVM 2556 +bcmring_evm_jazz MACH_BCMRING_EVM_JAZZ BCMRING_EVM_JAZZ 2557 +bcmring_sp MACH_BCMRING_SP BCMRING_SP 2558 +bcmring_sv MACH_BCMRING_SV BCMRING_SV 2559 +bcmring_sv_jazz MACH_BCMRING_SV_JAZZ BCMRING_SV_JAZZ 2560 +bcmring_tablet MACH_BCMRING_TABLET BCMRING_TABLET 2561 +bcmring_vp MACH_BCMRING_VP BCMRING_VP 2562 +bcmring_evm_seikor MACH_BCMRING_EVM_SEIKOR BCMRING_EVM_SEIKOR 2563 +bcmring_sp_wqvga MACH_BCMRING_SP_WQVGA BCMRING_SP_WQVGA 2564 +bcmring_custom MACH_BCMRING_CUSTOM BCMRING_CUSTOM 2565 +acer_s200 MACH_ACER_S200 ACER_S200 2566 +bt270 MACH_BT270 BT270 2567 +iseo MACH_ISEO ISEO 2568 +cezanne MACH_CEZANNE CEZANNE 2569 +lucca MACH_LUCCA LUCCA 2570 +supersmart MACH_SUPERSMART SUPERSMART 2571 +arm11_board MACH_CS_MISANO CS_MISANO 2572 +magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573 +emxx MACH_EMXX EMXX 2574 +outlaw MACH_OUTLAW OUTLAW 2575 riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576 +riot_gx2 MACH_RIOT_VOX RIOT_VOX 2577 riot_x37 MACH_RIOT_X37 RIOT_X37 2578 +mega25mx MACH_MEGA25MX MEGA25MX 2579 +benzina2 MACH_BENZINA2 BENZINA2 2580 +ignite MACH_IGNITE IGNITE 2581 +foggia MACH_FOGGIA FOGGIA 2582 +arezzo MACH_AREZZO AREZZO 2583 +leica_skywalker MACH_LEICA_SKYWALKER LEICA_SKYWALKER 2584 +jacinto2_jamr MACH_JACINTO2_JAMR JACINTO2_JAMR 2585 +gts_nova MACH_GTS_NOVA GTS_NOVA 2586 +p3600 MACH_P3600 P3600 2587 +dlt2 MACH_DLT2 DLT2 2588 +df3120 MACH_DF3120 DF3120 2589 +ecucore_9g20 MACH_ECUCORE_9G20 ECUCORE_9G20 2590 +nautel_am35xx MACH_NAUTEL_LPC3240 NAUTEL_LPC3240 2591 +glacier MACH_GLACIER GLACIER 2592 +phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593 +omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594 pca101 MACH_PCA101 PCA101 2595 +buzzc MACH_BUZZC BUZZC 2596 +sasie2 MACH_SASIE2 SASIE2 2597 +smartmeter_dl MACH_SMARTMETER_DL SMARTMETER_DL 2599 +wzl6410 MACH_WZL6410 WZL6410 2600 +wzl6410m MACH_WZL6410M WZL6410M 2601 +wzl6410f MACH_WZL6410F WZL6410F 2602 +wzl6410i MACH_WZL6410I WZL6410I 2603 +spacecom1 MACH_SPACECOM1 SPACECOM1 2604 +pingu920 MACH_PINGU920 PINGU920 2605 +bravoc MACH_BRAVOC BRAVOC 2606 +vdssw MACH_VDSSW VDSSW 2608 +romulus MACH_ROMULUS ROMULUS 2609 +omap_magic MACH_OMAP_MAGIC OMAP_MAGIC 2610 +eltd100 MACH_ELTD100 ELTD100 2611 capc7117 MACH_CAPC7117 CAPC7117 2612 +swan MACH_SWAN SWAN 2613 +veu MACH_VEU VEU 2614 +rm2 MACH_RM2 RM2 2615 +tt2100 MACH_TT2100 TT2100 2616 +venice MACH_VENICE VENICE 2617 +pc7323 MACH_PC7323 PC7323 2618 +masp MACH_MASP MASP 2619 +fujitsu_tvstbsoc0 MACH_FUJITSU_TVSTBSOC FUJITSU_TVSTBSOC 2620 +fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621 +lexikon MACH_LEXIKON LEXIKON 2622 +mini2440v2 MACH_MINI2440V2 MINI2440V2 2623 icontrol MACH_ICONTROL ICONTROL 2624 gplugd MACH_GPLUGD GPLUGD 2625 +qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626 qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627 +bee MACH_BEE BEE 2628 mx23evk MACH_MX23EVK MX23EVK 2629 ap4evb MACH_AP4EVB AP4EVB 2630 +stockholm MACH_STOCKHOLM STOCKHOLM 2631 +lpc_h3131 MACH_LPC_H3131 LPC_H3131 2632 +stingray MACH_STINGRAY STINGRAY 2633 +kraken MACH_KRAKEN KRAKEN 2634 +gw2388 MACH_GW2388 GW2388 2635 +jadecpu MACH_JADECPU JADECPU 2636 +carlisle MACH_CARLISLE CARLISLE 2637 +lux_sf9 MACH_LUX_SF9 LUX_SF9 2638 +nemid_tb MACH_NEMID_TB NEMID_TB 2639 +terrier MACH_TERRIER TERRIER 2640 +turbot MACH_TURBOT TURBOT 2641 +sanddab MACH_SANDDAB SANDDAB 2642 +mx35_cicada MACH_MX35_CICADA MX35_CICADA 2643 +ghi2703d MACH_GHI2703D GHI2703D 2644 +lux_sfx9 MACH_LUX_SFX9 LUX_SFX9 2645 +lux_sf9g MACH_LUX_SF9G LUX_SF9G 2646 +lux_edk9 MACH_LUX_EDK9 LUX_EDK9 2647 +hw90240 MACH_HW90240 HW90240 2648 +dm365_leopard MACH_DM365_LEOPARD DM365_LEOPARD 2649 mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650 +scat110 MACH_SCAT110 SCAT110 2651 +acer_a1 MACH_ACER_A1 ACER_A1 2652 +cmcontrol MACH_CMCONTROL CMCONTROL 2653 +pelco_lamar MACH_PELCO_LAMAR PELCO_LAMAR 2654 +rfp43 MACH_RFP43 RFP43 2655 +sk86r0301 MACH_SK86R0301 SK86R0301 2656 +ctpxa MACH_CTPXA CTPXA 2657 +epb_arm9_a MACH_EPB_ARM9_A EPB_ARM9_A 2658 guruplug MACH_GURUPLUG GURUPLUG 2659 spear310 MACH_SPEAR310 SPEAR310 2660 spear320 MACH_SPEAR320 SPEAR320 2661 +robotx MACH_ROBOTX ROBOTX 2662 +lsxhl MACH_LSXHL LSXHL 2663 +smartlite MACH_SMARTLITE SMARTLITE 2664 +cws2 MACH_CWS2 CWS2 2665 +m619 MACH_M619 M619 2666 +smartview MACH_SMARTVIEW SMARTVIEW 2667 +lsa_salsa MACH_LSA_SALSA LSA_SALSA 2668 +kizbox MACH_KIZBOX KIZBOX 2669 +htccharmer MACH_HTCCHARMER HTCCHARMER 2670 +guf_neso_lt MACH_GUF_NESO_LT GUF_NESO_LT 2671 +pm9g45 MACH_PM9G45 PM9G45 2672 +htcpanther MACH_HTCPANTHER HTCPANTHER 2673 +htcpanther_cdma MACH_HTCPANTHER_CDMA HTCPANTHER_CDMA 2674 +reb01 MACH_REB01 REB01 2675 aquila MACH_AQUILA AQUILA 2676 +spark_sls_hw2 MACH_SPARK_SLS_HW2 SPARK_SLS_HW2 2677 esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678 msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679 +micro2440 MACH_MICRO2440 MICRO2440 2680 +am2440 MACH_AM2440 AM2440 2681 +tq2440 MACH_TQ2440 TQ2440 2682 ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683 +ak880x MACH_AK880X AK880X 2684 +cobra3530 MACH_COBRA3530 COBRA3530 2685 +pmppb MACH_PMPPB PMPPB 2686 +u6715 MACH_U6715 U6715 2687 +axar1500_sender MACH_AXAR1500_SENDER AXAR1500_SENDER 2688 +g30_dvb MACH_G30_DVB G30_DVB 2689 +vc088x MACH_VC088X VC088X 2690 +mioa702 MACH_MIOA702 MIOA702 2691 +hpmin MACH_HPMIN HPMIN 2692 +ak880xak MACH_AK880XAK AK880XAK 2693 +arm926tomap850 MACH_ARM926TOMAP850 ARM926TOMAP850 2694 +lkevm MACH_LKEVM LKEVM 2695 +mw6410 MACH_MW6410 MW6410 2696 terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697 +cpu8000e MACH_CPU8000E CPU8000E 2698 +tokyo MACH_TOKYO TOKYO 2700 +msm7201a_surf MACH_MSM7201A_SURF MSM7201A_SURF 2701 +msm7201a_ffa MACH_MSM7201A_FFA MSM7201A_FFA 2702 msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703 msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704 msm7x27_surf MACH_MSM7X27_SURF MSM7X27_SURF 2705 msm7x27_ffa MACH_MSM7X27_FFA MSM7X27_FFA 2706 msm7x30_ffa MACH_MSM7X30_FFA MSM7X30_FFA 2707 qsd8x50_surf MACH_QSD8X50_SURF QSD8X50_SURF 2708 +qsd8x50_comet MACH_QSD8X50_COMET QSD8X50_COMET 2709 +qsd8x50_ffa MACH_QSD8X50_FFA QSD8X50_FFA 2710 +qsd8x50a_surf MACH_QSD8X50A_SURF QSD8X50A_SURF 2711 +qsd8x50a_ffa MACH_QSD8X50A_FFA QSD8X50A_FFA 2712 +adx_xgcp10 MACH_ADX_XGCP10 ADX_XGCP10 2713 +mcgwumts2a MACH_MCGWUMTS2A MCGWUMTS2A 2714 +mobikt MACH_MOBIKT MOBIKT 2715 mx53_evk MACH_MX53_EVK MX53_EVK 2716 igep0030 MACH_IGEP0030 IGEP0030 2717 +axell_h40_h50_ctrl MACH_AXELL_H40_H50_CTRL AXELL_H40_H50_CTRL 2718 +dtcommod MACH_DTCOMMOD DTCOMMOD 2719 +gould MACH_GOULD GOULD 2720 +siberia MACH_SIBERIA SIBERIA 2721 sbc3530 MACH_SBC3530 SBC3530 2722 +qarm MACH_QARM QARM 2723 +mips MACH_MIPS MIPS 2724 +mx27grb MACH_MX27GRB MX27GRB 2725 +sbc8100 MACH_SBC8100 SBC8100 2726 saarb MACH_SAARB SAARB 2727 +omap3mini MACH_OMAP3MINI OMAP3MINI 2728 +cnmbook7se MACH_CNMBOOK7SE CNMBOOK7SE 2729 +catan MACH_CATAN CATAN 2730 harmony MACH_HARMONY HARMONY 2731 +tonga MACH_TONGA TONGA 2732 +cybook_orizon MACH_CYBOOK_ORIZON CYBOOK_ORIZON 2733 +htcrhodiumcdma MACH_HTCRHODIUMCDMA HTCRHODIUMCDMA 2734 +epc_g45 MACH_EPC_G45 EPC_G45 2735 +epc_lpc3250 MACH_EPC_LPC3250 EPC_LPC3250 2736 +mxc91341evb MACH_MXC91341EVB MXC91341EVB 2737 +rtw1000 MACH_RTW1000 RTW1000 2738 +bobcat MACH_BOBCAT BOBCAT 2739 +trizeps6 MACH_TRIZEPS6 TRIZEPS6 2740 msm7x30_fluid MACH_MSM7X30_FLUID MSM7X30_FLUID 2741 +nedap9263 MACH_NEDAP9263 NEDAP9263 2742 +netgear_ms2110 MACH_NETGEAR_MS2110 NETGEAR_MS2110 2743 +bmx MACH_BMX BMX 2744 +netstream MACH_NETSTREAM NETSTREAM 2745 +vpnext_rcu MACH_VPNEXT_RCU VPNEXT_RCU 2746 +vpnext_mpu MACH_VPNEXT_MPU VPNEXT_MPU 2747 +bcmring_tablet_v1 MACH_BCMRING_TABLET_V1 BCMRING_TABLET_V1 2748 +sgarm10 MACH_SGARM10 SGARM10 2749 cm_t3517 MACH_CM_T3517 CM_T3517 2750 +dig297 MACH_OMAP3_CPS OMAP3_CPS 2751 +axar1500_receiver MACH_AXAR1500_RECEIVER AXAR1500_RECEIVER 2752 wbd222 MACH_WBD222 WBD222 2753 +mt65xx MACH_MT65XX MT65XX 2754 msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755 msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756 tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758 nanos MACH_NANOS NANOS 2759 +stamp9g10 MACH_STAMP9G10 STAMP9G10 2760 stamp9g45 MACH_STAMP9G45 STAMP9G45 2761 +h6053 MACH_H6053 H6053 2762 +smint01 MACH_SMINT01 SMINT01 2763 +prtlvt2 MACH_PRTLVT2 PRTLVT2 2764 +ap420 MACH_AP420 AP420 2765 +davinci_dm365_fc MACH_DAVINCI_DM365_FC DAVINCI_DM365_FC 2767 +msm8x55_surf MACH_MSM8X55_SURF MSM8X55_SURF 2768 +msm8x55_ffa MACH_MSM8X55_FFA MSM8X55_FFA 2769 +esl_vamana MACH_ESL_VAMANA ESL_VAMANA 2770 +sbc35 MACH_SBC35 SBC35 2771 +mpx6446 MACH_MPX6446 MPX6446 2772 +oreo_controller MACH_OREO_CONTROLLER OREO_CONTROLLER 2773 +kopin_models MACH_KOPIN_MODELS KOPIN_MODELS 2774 +ttc_vision2 MACH_TTC_VISION2 TTC_VISION2 2775 cns3420vb MACH_CNS3420VB CNS3420VB 2776 +lpc_evo MACH_LPC2 LPC2 2777 +olympus MACH_OLYMPUS OLYMPUS 2778 +vortex MACH_VORTEX VORTEX 2779 +s5pc200 MACH_S5PC200 S5PC200 2780 +ecucore_9263 MACH_ECUCORE_9263 ECUCORE_9263 2781 +smdkc200 MACH_SMDKC200 SMDKC200 2782 +emsiso_sx27 MACH_EMSISO_SX27 EMSISO_SX27 2783 +apx_som9g45_ek MACH_APX_SOM9G45_EK APX_SOM9G45_EK 2784 +songshan MACH_SONGSHAN SONGSHAN 2785 +tianshan MACH_TIANSHAN TIANSHAN 2786 +vpx500 MACH_VPX500 VPX500 2787 +am3517sam MACH_AM3517SAM AM3517SAM 2788 +skat91_sim508 MACH_SKAT91_SIM508 SKAT91_SIM508 2789 +skat91_s3e MACH_SKAT91_S3E SKAT91_S3E 2790 omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791 +df7220 MACH_DF7220 DF7220 2792 +nemini MACH_NEMINI NEMINI 2793 +t8200 MACH_T8200 T8200 2794 +apf51 MACH_APF51 APF51 2795 +dr_rc_unit MACH_DR_RC_UNIT DR_RC_UNIT 2796 +bordeaux MACH_BORDEAUX BORDEAUX 2797 +catania_b MACH_CATANIA_B CATANIA_B 2798 +mx51_ocean MACH_MX51_OCEAN MX51_OCEAN 2799 ti8168evm MACH_TI8168EVM TI8168EVM 2800 +neocoreomap MACH_NEOCOREOMAP NEOCOREOMAP 2801 +withings_wbp MACH_WITHINGS_WBP WITHINGS_WBP 2802 +dbps MACH_DBPS DBPS 2803 +pcbfp0001 MACH_PCBFP0001 PCBFP0001 2805 +speedy MACH_SPEEDY SPEEDY 2806 +chrysaor MACH_CHRYSAOR CHRYSAOR 2807 +tango MACH_TANGO TANGO 2808 +synology_dsx11 MACH_SYNOLOGY_DSX11 SYNOLOGY_DSX11 2809 +hanlin_v3ext MACH_HANLIN_V3EXT HANLIN_V3EXT 2810 +hanlin_v5 MACH_HANLIN_V5 HANLIN_V5 2811 +hanlin_v3plus MACH_HANLIN_V3PLUS HANLIN_V3PLUS 2812 +iriver_story MACH_IRIVER_STORY IRIVER_STORY 2813 +irex_iliad MACH_IREX_ILIAD IREX_ILIAD 2814 +irex_dr1000 MACH_IREX_DR1000 IREX_DR1000 2815 teton_bga MACH_TETON_BGA TETON_BGA 2816 +snapper9g45 MACH_SNAPPER9G45 SNAPPER9G45 2817 +tam3517 MACH_TAM3517 TAM3517 2818 +pdc100 MACH_PDC100 PDC100 2819 eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25SD EUKREA_CPUIMX25SD 2820 eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821 eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822 eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823 +p565 MACH_P565 P565 2824 +acer_a4 MACH_ACER_A4 ACER_A4 2825 +davinci_dm368_bip MACH_DAVINCI_DM368_BIP DAVINCI_DM368_BIP 2826 +eshare MACH_ESHARE ESHARE 2827 +wlbargn MACH_WLBARGN WLBARGN 2829 +bm170 MACH_BM170 BM170 2830 +netspace_mini_v2 MACH_NETSPACE_MINI_V2 NETSPACE_MINI_V2 2831 +netspace_plug_v2 MACH_NETSPACE_PLUG_V2 NETSPACE_PLUG_V2 2832 +siemens_l1 MACH_SIEMENS_L1 SIEMENS_L1 2833 +elv_lcu1 MACH_ELV_LCU1 ELV_LCU1 2834 +mcu1 MACH_MCU1 MCU1 2835 +omap3_tao3530 MACH_OMAP3_TAO3530 OMAP3_TAO3530 2836 +omap3_pcutouch MACH_OMAP3_PCUTOUCH OMAP3_PCUTOUCH 2837 smdkc210 MACH_SMDKC210 SMDKC210 2838 -pca102 MACH_PCA102 PCA102 2843 +omap3_braillo MACH_OMAP3_BRAILLO OMAP3_BRAILLO 2839 +spyplug MACH_SPYPLUG SPYPLUG 2840 +ginger MACH_GINGER GINGER 2841 +tny_t3530 MACH_TNY_T3530 TNY_T3530 2842 +pcaal1 MACH_PCAAL1 PCAAL1 2843 +spade MACH_SPADE SPADE 2844 +mxc25_topaz MACH_MXC25_TOPAZ MXC25_TOPAZ 2845 t5325 MACH_T5325 T5325 2846 +gw2361 MACH_GW2361 GW2361 2847 +elog MACH_ELOG ELOG 2848 income MACH_INCOME INCOME 2849 +bcm589x MACH_BCM589X BCM589X 2850 +etna MACH_ETNA ETNA 2851 +hawks MACH_HAWKS HAWKS 2852 +meson MACH_MESON MESON 2853 +xsbase255 MACH_XSBASE255 XSBASE255 2854 +pvm2030 MACH_PVM2030 PVM2030 2855 +mioa502 MACH_MIOA502 MIOA502 2856 vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2 2857 vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2 2858 vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859 +htc_spv_m700 MACH_HTC_SPV_M700 HTC_SPV_M700 2860 mx257sx MACH_MX257SX MX257SX 2861 goni MACH_GONI GONI 2862 +msm8x55_svlte_ffa MACH_MSM8X55_SVLTE_FFA MSM8X55_SVLTE_FFA 2863 +msm8x55_svlte_surf MACH_MSM8X55_SVLTE_SURF MSM8X55_SVLTE_SURF 2864 +quickstep MACH_QUICKSTEP QUICKSTEP 2865 +dmw96 MACH_DMW96 DMW96 2866 +hammerhead MACH_HAMMERHEAD HAMMERHEAD 2867 +trident MACH_TRIDENT TRIDENT 2868 +lightning MACH_LIGHTNING LIGHTNING 2869 +iconnect MACH_ICONNECT ICONNECT 2870 +autobot MACH_AUTOBOT AUTOBOT 2871 +coconut MACH_COCONUT COCONUT 2872 +durian MACH_DURIAN DURIAN 2873 +cayenne MACH_CAYENNE CAYENNE 2874 +fuji MACH_FUJI FUJI 2875 +synology_6282 MACH_SYNOLOGY_6282 SYNOLOGY_6282 2876 +em1sy MACH_EM1SY EM1SY 2877 +m502 MACH_M502 M502 2878 +matrix518 MACH_MATRIX518 MATRIX518 2879 +tiny_gurnard MACH_TINY_GURNARD TINY_GURNARD 2880 +spear1310 MACH_SPEAR1310 SPEAR1310 2881 bv07 MACH_BV07 BV07 2882 +mxt_td61 MACH_MXT_TD61 MXT_TD61 2883 openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884 devixp MACH_DEVIXP DEVIXP 2885 miccpt MACH_MICCPT MICCPT 2886 mic256 MACH_MIC256 MIC256 2887 +as1167 MACH_AS1167 AS1167 2888 +omap3_ibiza MACH_OMAP3_IBIZA OMAP3_IBIZA 2889 u5500 MACH_U5500 U5500 2890 +davinci_picto MACH_DAVINCI_PICTO DAVINCI_PICTO 2891 +mecha MACH_MECHA MECHA 2892 +bubba3 MACH_BUBBA3 BUBBA3 2893 +pupitre MACH_PUPITRE PUPITRE 2894 +tegra_vogue MACH_TEGRA_VOGUE TEGRA_VOGUE 2896 +tegra_e1165 MACH_TEGRA_E1165 TEGRA_E1165 2897 +simplenet MACH_SIMPLENET SIMPLENET 2898 +ec4350tbm MACH_EC4350TBM EC4350TBM 2899 +pec_tc MACH_PEC_TC PEC_TC 2900 +pec_hc2 MACH_PEC_HC2 PEC_HC2 2901 +esl_mobilis_a MACH_ESL_MOBILIS_A ESL_MOBILIS_A 2902 +esl_mobilis_b MACH_ESL_MOBILIS_B ESL_MOBILIS_B 2903 +esl_wave_a MACH_ESL_WAVE_A ESL_WAVE_A 2904 +esl_wave_b MACH_ESL_WAVE_B ESL_WAVE_B 2905 +unisense_mmm MACH_UNISENSE_MMM UNISENSE_MMM 2906 +blueshark MACH_BLUESHARK BLUESHARK 2907 +e10 MACH_E10 E10 2908 +app3k_robin MACH_APP3K_ROBIN APP3K_ROBIN 2909 +pov15hd MACH_POV15HD POV15HD 2910 +stella MACH_STELLA STELLA 2911 linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913 +netwalker MACH_NETWALKER NETWALKER 2914 +acsx106 MACH_ACSX106 ACSX106 2915 +atlas5_c1 MACH_ATLAS5_C1 ATLAS5_C1 2916 +nsb3ast MACH_NSB3AST NSB3AST 2917 +gnet_slc MACH_GNET_SLC GNET_SLC 2918 +af4000 MACH_AF4000 AF4000 2919 +ark9431 MACH_ARK9431 ARK9431 2920 +fs_s5pc100 MACH_FS_S5PC100 FS_S5PC100 2921 +omap3505nova8 MACH_OMAP3505NOVA8 OMAP3505NOVA8 2922 +omap3621_edp1 MACH_OMAP3621_EDP1 OMAP3621_EDP1 2923 +oratisaes MACH_ORATISAES ORATISAES 2924 smdkv310 MACH_SMDKV310 SMDKV310 2925 +siemens_l0 MACH_SIEMENS_L0 SIEMENS_L0 2926 +ventana MACH_VENTANA VENTANA 2927 wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928 +ec4350sdb MACH_EC4350SDB EC4350SDB 2929 +mimas MACH_MIMAS MIMAS 2930 +titan MACH_TITAN TITAN 2931 craneboard MACH_CRANEBOARD CRANEBOARD 2932 +es2440 MACH_ES2440 ES2440 2933 +najay_a9263 MACH_NAJAY_A9263 NAJAY_A9263 2934 +htctornado MACH_HTCTORNADO HTCTORNADO 2935 +dimm_mx257 MACH_DIMM_MX257 DIMM_MX257 2936 +jigen301 MACH_JIGEN JIGEN 2937 smdk6450 MACH_SMDK6450 SMDK6450 2938 +meno_qng MACH_MENO_QNG MENO_QNG 2939 +ns2416 MACH_NS2416 NS2416 2940 +rpc353 MACH_RPC353 RPC353 2941 +tq6410 MACH_TQ6410 TQ6410 2942 +sky6410 MACH_SKY6410 SKY6410 2943 +dynasty MACH_DYNASTY DYNASTY 2944 +vivo MACH_VIVO VIVO 2945 +bury_bl7582 MACH_BURY_BL7582 BURY_BL7582 2946 +bury_bps5270 MACH_BURY_BPS5270 BURY_BPS5270 2947 +basi MACH_BASI BASI 2948 +tn200 MACH_TN200 TN200 2949 +c2mmi MACH_C2MMI C2MMI 2950 +meson_6236m MACH_MESON_6236M MESON_6236M 2951 +meson_8626m MACH_MESON_8626M MESON_8626M 2952 +tube MACH_TUBE TUBE 2953 +messina MACH_MESSINA MESSINA 2954 +mx50_arm2 MACH_MX50_ARM2 MX50_ARM2 2955 +cetus9263 MACH_CETUS9263 CETUS9263 2956 brownstone MACH_BROWNSTONE BROWNSTONE 2957 +vmx25 MACH_VMX25 VMX25 2958 +vmx51 MACH_VMX51 VMX51 2959 +abacus MACH_ABACUS ABACUS 2960 +cm4745 MACH_CM4745 CM4745 2961 +oratislink MACH_ORATISLINK ORATISLINK 2962 +davinci_dm365_dvr MACH_DAVINCI_DM365_DVR DAVINCI_DM365_DVR 2963 +netviz MACH_NETVIZ NETVIZ 2964 flexibity MACH_FLEXIBITY FLEXIBITY 2965 +wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966 +lpc24xx MACH_LPC24XX LPC24XX 2967 +spica MACH_SPICA SPICA 2968 +gpsdisplay MACH_GPSDISPLAY GPSDISPLAY 2969 +bipnet MACH_BIPNET BIPNET 2970 +overo_ctu_inertial MACH_OVERO_CTU_INERTIAL OVERO_CTU_INERTIAL 2971 +davinci_dm355_mmm MACH_DAVINCI_DM355_MMM DAVINCI_DM355_MMM 2972 +pc9260_v2 MACH_PC9260_V2 PC9260_V2 2973 +ptx7545 MACH_PTX7545 PTX7545 2974 +tm_efdc MACH_TM_EFDC TM_EFDC 2975 +omap3_waldo1 MACH_OMAP3_WALDO1 OMAP3_WALDO1 2977 +flyer MACH_FLYER FLYER 2978 +tornado3240 MACH_TORNADO3240 TORNADO3240 2979 +soli_01 MACH_SOLI_01 SOLI_01 2980 +omapl138_europalc MACH_OMAPL138_EUROPALC OMAPL138_EUROPALC 2981 +helios_v1 MACH_HELIOS_V1 HELIOS_V1 2982 +netspace_lite_v2 MACH_NETSPACE_LITE_V2 NETSPACE_LITE_V2 2983 +ssc MACH_SSC SSC 2984 +premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 +wasabi MACH_WASABI WASABI 2986 mx50_rdp MACH_MX50_RDP MX50_RDP 2988 universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989 real6410 MACH_REAL6410 REAL6410 2990 +spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 +ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 +omap3_bc10 MACH_OMAP3_BC10 OMAP3_BC10 2993 +thebe MACH_THEBE THEBE 2994 +rv082 MACH_RV082 RV082 2995 +armlguest MACH_ARMLGUEST ARMLGUEST 2996 +tjinc1000 MACH_TJINC1000 TJINC1000 2997 dockstar MACH_DOCKSTAR DOCKSTAR 2998 +ax8008 MACH_AX8008 AX8008 2999 +gnet_sgce MACH_GNET_SGCE GNET_SGCE 3000 +pxwnas_500_1000 MACH_PXWNAS_500_1000 PXWNAS_500_1000 3001 +ea20 MACH_EA20 EA20 3002 +awm2 MACH_AWM2 AWM2 3003 ti8148evm MACH_TI8148EVM TI8148EVM 3004 seaboard MACH_SEABOARD SEABOARD 3005 +linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006 +tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007 +rubys MACH_RUBYS RUBYS 3008 +aquarius MACH_AQUARIUS AQUARIUS 3009 mx53_ard MACH_MX53_ARD MX53_ARD 3010 mx53_smd MACH_MX53_SMD MX53_SMD 3011 +lswxl MACH_LSWXL LSWXL 3012 +dove_avng_v3 MACH_DOVE_AVNG_V3 DOVE_AVNG_V3 3013 +sdi_ess_9263 MACH_SDI_ESS_9263 SDI_ESS_9263 3014 +jocpu550 MACH_JOCPU550 JOCPU550 3015 msm8x60_rumi3 MACH_MSM8X60_RUMI3 MSM8X60_RUMI3 3016 msm8x60_ffa MACH_MSM8X60_FFA MSM8X60_FFA 3017 +yanomami MACH_YANOMAMI YANOMAMI 3018 +gta04 MACH_GTA04 GTA04 3019 cm_a510 MACH_CM_A510 CM_A510 3020 +omap3_rfs200 MACH_OMAP3_RFS200 OMAP3_RFS200 3021 +kx33xx MACH_KX33XX KX33XX 3022 +ptx7510 MACH_PTX7510 PTX7510 3023 +top9000 MACH_TOP9000 TOP9000 3024 +teenote MACH_TEENOTE TEENOTE 3025 +ts3 MACH_TS3 TS3 3026 +a0 MACH_A0 A0 3027 +fsm9xxx_surf MACH_FSM9XXX_SURF FSM9XXX_SURF 3028 +fsm9xxx_ffa MACH_FSM9XXX_FFA FSM9XXX_FFA 3029 +frrhwcdma60w MACH_FRRHWCDMA60W FRRHWCDMA60W 3030 +remus MACH_REMUS REMUS 3031 +at91cap7xdk MACH_AT91CAP7XDK AT91CAP7XDK 3032 +at91cap7stk MACH_AT91CAP7STK AT91CAP7STK 3033 +kt_sbc_sam9_1 MACH_KT_SBC_SAM9_1 KT_SBC_SAM9_1 3034 +armada_xp_db MACH_ARMADA_XP_DB ARMADA_XP_DB 3036 +spdm MACH_SPDM SPDM 3037 +gtib MACH_GTIB GTIB 3038 +dgm3240 MACH_DGM3240 DGM3240 3039 +htcmega MACH_HTCMEGA HTCMEGA 3041 +tricorder MACH_TRICORDER TRICORDER 3042 tx28 MACH_TX28 TX28 3043 +bstbrd MACH_BSTBRD BSTBRD 3044 +pwb3090 MACH_PWB3090 PWB3090 3045 +idea6410 MACH_IDEA6410 IDEA6410 3046 +qbc9263 MACH_QBC9263 QBC9263 3047 +borabora MACH_BORABORA BORABORA 3048 +valdez MACH_VALDEZ VALDEZ 3049 +ls9g20 MACH_LS9G20 LS9G20 3050 +mios_v1 MACH_MIOS_V1 MIOS_V1 3051 +s5pc110_crespo MACH_S5PC110_CRESPO S5PC110_CRESPO 3052 +controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053 +tin307 MACH_TIN307 TIN307 3054 +tin510 MACH_TIN510 TIN510 3055 +ep3505 MACH_EP3517 EP3517 3056 +bluecheese MACH_BLUECHEESE BLUECHEESE 3057 +tem3x30 MACH_TEM3X30 TEM3X30 3058 +harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 +msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 +spear900 MACH_SPEAR900 SPEAR900 3061 pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 +rdstor MACH_RDSTOR RDSTOR 3063 +usdloader MACH_USDLOADER USDLOADER 3064 +tsoploader MACH_TSOPLOADER TSOPLOADER 3065 +kronos MACH_KRONOS KRONOS 3066 +ffcore MACH_FFCORE FFCORE 3067 +mone MACH_MONE MONE 3068 +unit2s MACH_UNIT2S UNIT2S 3069 +acer_a5 MACH_ACER_A5 ACER_A5 3070 +etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071 +stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072 +p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073 +tulip MACH_TULIP TULIP 3074 +sunflower MACH_SUNFLOWER SUNFLOWER 3075 +rib MACH_RIB RIB 3076 +clod MACH_CLOD CLOD 3077 +rump MACH_RUMP RUMP 3078 +tenderloin MACH_TENDERLOIN TENDERLOIN 3079 +shortloin MACH_SHORTLOIN SHORTLOIN 3080 +antares MACH_ANTARES ANTARES 3082 +wb40n MACH_WB40N WB40N 3083 +herring MACH_HERRING HERRING 3084 +naxy400 MACH_NAXY400 NAXY400 3085 +naxy1200 MACH_NAXY1200 NAXY1200 3086 vpr200 MACH_VPR200 VPR200 3087 +bug20 MACH_BUG20 BUG20 3088 +goflexnet MACH_GOFLEXNET GOFLEXNET 3089 torbreck MACH_TORBRECK TORBRECK 3090 +saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091 +callisto MACH_CALLISTO CALLISTO 3092 +multhsu MACH_MULTHSU MULTHSU 3093 +saluda MACH_SALUDA SALUDA 3094 +pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095 +vc0718 MACH_VC0718 VC0718 3096 +mvblx MACH_MVBLX MVBLX 3097 +inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098 +inhand_fury MACH_INHAND_FURY INHAND_FURY 3099 +inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100 +hdnvp MACH_HDNVP HDNVP 3101 +softwinner MACH_SOFTWINNER SOFTWINNER 3102 prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 +nas6210 MACH_NAS6210 NAS6210 3104 +unisdev MACH_UNISDEV UNISDEV 3105 +sbca11 MACH_SBCA11 SBCA11 3106 +saga MACH_SAGA SAGA 3107 +ns_k330 MACH_NS_K330 NS_K330 3108 +tanna MACH_TANNA TANNA 3109 +imate8502 MACH_IMATE8502 IMATE8502 3110 +aspen MACH_ASPEN ASPEN 3111 +daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112 +zmx25 MACH_ZMX25 ZMX25 3113 +maple1 MACH_MAPLE1 MAPLE1 3114 +qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115 +qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116 +abilene MACH_ABILENE ABILENE 3117 +eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118 +iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119 +coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120 +santiago MACH_SANTIAGO SANTIAGO 3121 +mx257sol MACH_MX257SOL MX257SOL 3122 +strasbourg MACH_STRASBOURG STRASBOURG 3123 +msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124 +smartqv5 MACH_SMARTQV5 SMARTQV5 3125 +smartqv3 MACH_SMARTQV3 SMARTQV3 3126 +smartqv7 MACH_SMARTQV7 SMARTQV7 3127 paz00 MACH_PAZ00 PAZ00 3128 acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 +fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131 +hdgu MACH_HDGU HDGU 3132 +pyramid MACH_PYRAMID PYRAMID 3133 +epiphan MACH_EPIPHAN EPIPHAN 3134 +omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135 +gurnard MACH_GURNARD GURNARD 3136 +gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137 +bcm2708 MACH_BCM2708 BCM2708 3138 +mx51_ggc MACH_MX51_GGC MX51_GGC 3139 +sharespace MACH_SHARESPACE SHARESPACE 3140 +haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141 +simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142 +crux MACH_CRUX CRUX 3143 +mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144 +charon MACH_CHARON CHARON 3145 +picocom3 MACH_PICOCOM3 PICOCOM3 3146 +picocom4 MACH_PICOCOM4 PICOCOM4 3147 +serrano MACH_SERRANO SERRANO 3148 +doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149 +evsy MACH_EVSY EVSY 3150 +huashan MACH_HUASHAN HUASHAN 3151 +lausanne MACH_LAUSANNE LAUSANNE 3152 +emerald MACH_EMERALD EMERALD 3153 +tqma35 MACH_TQMA35 TQMA35 3154 +marvel MACH_MARVEL MARVEL 3155 +manuae MACH_MANUAE MANUAE 3156 +chacha MACH_CHACHA CHACHA 3157 +lemon MACH_LEMON LEMON 3158 +csc MACH_CSC CSC 3159 +gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160 +t20 MACH_T20 T20 3161 +hdmini MACH_HDMINI HDMINI 3162 +sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163 +express MACH_EXPRESS EXPRESS 3164 +express_kt MACH_EXPRESS_KT EXPRESS_KT 3165 +maximasp MACH_MAXIMASP MAXIMASP 3166 +nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167 +nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168 +sunfire MACH_SUNFIRE SUNFIRE 3169 +arowana MACH_AROWANA AROWANA 3170 +tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171 +tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172 +edison MACH_EDISON EDISON 3173 +svp8500v1 MACH_SVP8500V1 SVP8500V1 3174 +svp8500v2 MACH_SVP8500V2 SVP8500V2 3175 +svp5500 MACH_SVP5500 SVP5500 3176 +b5500 MACH_B5500 B5500 3177 +s5500 MACH_S5500 S5500 3178 +icon MACH_ICON ICON 3179 +elephant MACH_ELEPHANT ELEPHANT 3180 +shooter MACH_SHOOTER SHOOTER 3182 +spade_lte MACH_SPADE_LTE SPADE_LTE 3183 +philhwani MACH_PHILHWANI PHILHWANI 3184 +gsncomm MACH_GSNCOMM GSNCOMM 3185 +strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186 +mmm MACH_MMM MMM 3187 +davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188 ag5evm MACH_AG5EVM AG5EVM 3189 +sc575plc MACH_SC575PLC SC575PLC 3190 +sc575hmi MACH_SC575IPC SC575IPC 3191 +omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192 +top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194 +top9000_su MACH_TOP9000_SU TOP9000_SU 3195 +utm300 MACH_UTM300 UTM300 3196 tsunagi MACH_TSUNAGI TSUNAGI 3197 +ts75xx MACH_TS75XX TS75XX 3198 +ts47xx MACH_TS47XX TS47XX 3200 +da850_k5 MACH_DA850_K5 DA850_K5 3201 +ax502 MACH_AX502 AX502 3202 +igep0032 MACH_IGEP0032 IGEP0032 3203 +antero MACH_ANTERO ANTERO 3204 +synergy MACH_SYNERGY SYNERGY 3205 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 +punica MACH_PUNICA PUNICA 3208 trimslice MACH_TRIMSLICE TRIMSLICE 3209 +mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 mackerel MACH_MACKEREL MACKEREL 3211 +fa9x27 MACH_FA9X27 FA9X27 3213 +ns2816tb MACH_NS2816TB NS2816TB 3214 +ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215 +ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216 kaen MACH_KAEN KAEN 3217 +nv1000 MACH_NV1000 NV1000 3218 +nuc950ts MACH_NUC950TS NUC950TS 3219 nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 +ast2200 MACH_AST2200 AST2200 3221 +lead MACH_LEAD LEAD 3222 +unino1 MACH_UNINO1 UNINO1 3223 +greeco MACH_GREECO GREECO 3224 +verdi MACH_VERDI VERDI 3225 dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 @@ -603,7 +3251,9 @@ isc3 MACH_ISC3 ISC3 3291 rascal MACH_RASCAL RASCAL 3292 hrefv60 MACH_HREFV60 HREFV60 3293 tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294 +pydtd MACH_PYRAMID_TD PYRAMID_TD 3295 splendor MACH_SPLENDOR SPLENDOR 3296 +guf_vincell MACH_GUF_PLANET GUF_PLANET 3297 msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298 htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299 athene MACH_ATHENE ATHENE 3300 @@ -614,6 +3264,7 @@ rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304 nmh MACH_NMH NMH 3305 wn802t MACH_WN802T WN802T 3306 dragonet MACH_DRAGONET DRAGONET 3307 +geneva_b4 MACH_GENEVA_B GENEVA_B 3308 at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309 bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310 bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311 @@ -621,11 +3272,13 @@ koi MACH_KOI KOI 3312 ts4800 MACH_TS4800 TS4800 3313 tqma9263 MACH_TQMA9263 TQMA9263 3314 holiday MACH_HOLIDAY HOLIDAY 3315 +dma_6410 MACH_DMA6410 DMA6410 3316 pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317 hwgw6410 MACH_HWGW6410 HWGW6410 3318 shenzhou MACH_SHENZHOU SHENZHOU 3319 cwme9210 MACH_CWME9210 CWME9210 3320 cwme9210js MACH_CWME9210JS CWME9210JS 3321 +pgs_v1 MACH_PGS_SITARA PGS_SITARA 3322 colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323 w21 MACH_W21 W21 3324 polysat1 MACH_POLYSAT1 POLYSAT1 3325 @@ -691,11 +3344,15 @@ viprinet MACH_VIPRINET VIPRINET 3385 bockw MACH_BOCKW BOCKW 3386 eva2000 MACH_EVA2000 EVA2000 3387 steelyard MACH_STEELYARD STEELYARD 3388 +ea2468devkit MACH_LPC2468OEM LPC2468OEM 3389 +sdh001 MACH_MACH_SDH001 MACH_SDH001 3390 +fe2478mblox MACH_LPC2478MICROBLOX LPC2478MICROBLOX 3391 nsslsboard MACH_NSSLSBOARD NSSLSBOARD 3392 geneva_b5 MACH_GENEVA_B5 GENEVA_B5 3393 spear1340 MACH_SPEAR1340 SPEAR1340 3394 rexmas MACH_REXMAS REXMAS 3395 msm8960_cdp MACH_MSM8960_CDP MSM8960_CDP 3396 +msm8960_mtp MACH_MSM8960_MDP MSM8960_MDP 3397 msm8960_fluid MACH_MSM8960_FLUID MSM8960_FLUID 3398 msm8960_apq MACH_MSM8960_APQ MSM8960_APQ 3399 helios_v2 MACH_HELIOS_V2 HELIOS_V2 3400 @@ -727,6 +3384,7 @@ gt_i5700 MACH_GT_I5700 GT_I5700 3425 ctera_plug_c2 MACH_CTERA_PLUG_C2 CTERA_PLUG_C2 3426 marvelct MACH_MARVELCT MARVELCT 3427 ag11005 MACH_AG11005 AG11005 3428 +omap_tabletblaze MACH_OMAP_BLAZE OMAP_BLAZE 3429 vangogh MACH_VANGOGH VANGOGH 3430 matrix505 MACH_MATRIX505 MATRIX505 3431 oce_nigma MACH_OCE_NIGMA OCE_NIGMA 3432 @@ -766,6 +3424,7 @@ h1600 MACH_H1600 H1600 3465 mini210 MACH_MINI210 MINI210 3466 mini8168 MACH_MINI8168 MINI8168 3467 pc7308 MACH_PC7308 PC7308 3468 +ge863pro3 MACH_GE863 GE863 3469 kmm2m01 MACH_KMM2M01 KMM2M01 3470 mx51erebus MACH_MX51EREBUS MX51EREBUS 3471 wm8650refboard MACH_WM8650REFBOARD WM8650REFBOARD 3472 @@ -802,6 +3461,7 @@ shooter_k MACH_SHOOTER_K SHOOTER_K 3502 nspire MACH_NSPIRE NSPIRE 3503 mickxx MACH_MICKXX MICKXX 3504 lxmb MACH_LXMB LXMB 3505 +tmdxscbp6618x MACH_TMDXSCBP6616X TMDXSCBP6616X 3506 adam MACH_ADAM ADAM 3507 b1004 MACH_B1004 B1004 3508 oboea MACH_OBOEA OBOEA 3509 @@ -879,6 +3539,7 @@ bct MACH_BCT BCT 3582 tuscan MACH_TUSCAN TUSCAN 3583 xbt_sam9g45 MACH_XBT_SAM9G45 XBT_SAM9G45 3584 enbw_cmc MACH_ENBW_CMC ENBW_CMC 3585 +msm8x60_dragon MACH_APQ8060_DRAGON APQ8060_DRAGON 3586 ch104mx257 MACH_CH104MX257 CH104MX257 3587 openpri MACH_OPENPRI OPENPRI 3588 am335xevm MACH_AM335XEVM AM335XEVM 3589 @@ -900,6 +3561,7 @@ cinema MACH_CINEMA CINEMA 3604 cinema_tea MACH_CINEMA_TEA CINEMA_TEA 3605 cinema_coffee MACH_CINEMA_COFFEE CINEMA_COFFEE 3606 cinema_juice MACH_CINEMA_JUICE CINEMA_JUICE 3607 +linux_pad MACH_THEPAD THEPAD 3608 mx53_mirage2 MACH_MX53_MIRAGE2 MX53_MIRAGE2 3609 mx53_efikasb MACH_MX53_EFIKASB MX53_EFIKASB 3610 stm_b2000 MACH_STM_B2000 STM_B2000 3612 @@ -965,6 +3627,7 @@ pia_am35x MACH_PIA_AM35X PIA_AM35X 3671 cedar MACH_CEDAR CEDAR 3672 picasso_e MACH_PICASSO_E PICASSO_E 3673 samsung_e60 MACH_SAMSUNG_E60 SAMSUNG_E60 3674 +msm9615_cdp MACH_MDM9615 MDM9615 3675 sdvr_mini MACH_SDVR_MINI SDVR_MINI 3676 omap3_ij3k MACH_OMAP3_IJ3K OMAP3_IJ3K 3677 modasmc1 MACH_MODASMC1 MODASMC1 3678 @@ -992,6 +3655,8 @@ fmc_uic MACH_FMC_UIC FMC_UIC 3699 fmc_dcm MACH_FMC_DCM FMC_DCM 3700 batwm MACH_BATWM BATWM 3701 atlas6cb MACH_ATLAS6CB ATLAS6CB 3702 +quattro_f MACH_QUATTROF QUATTROF 3703 +quattro_u MACH_QUATTROU QUATTROU 3704 blue MACH_BLUE BLUE 3705 colorado MACH_COLORADO COLORADO 3706 popc MACH_POPC POPC 3707 @@ -999,15 +3664,19 @@ promwad_jade MACH_PROMWAD_JADE PROMWAD_JADE 3708 amp MACH_AMP AMP 3709 gnet_amp MACH_GNET_AMP GNET_AMP 3710 toques MACH_TOQUES TOQUES 3711 +apx4devkit MACH_APX4DEVKIT APX4DEVKIT 3712 dct_storm MACH_DCT_STORM DCT_STORM 3713 +dm8168z3 MACH_Z3 Z3 3714 owl MACH_OWL OWL 3715 cogent_csb1741 MACH_COGENT_CSB1741 COGENT_CSB1741 3716 +omap3_kiko MACH_OMAP3 OMAP3 3717 adillustra610 MACH_ADILLUSTRA610 ADILLUSTRA610 3718 ecafe_na04 MACH_ECAFE_NA04 ECAFE_NA04 3719 popct MACH_POPCT POPCT 3720 omap3_helena MACH_OMAP3_HELENA OMAP3_HELENA 3721 ach MACH_ACH ACH 3722 module_dtb MACH_MODULE_DTB MODULE_DTB 3723 +ratebox MACH_RACKBOX RACKBOX 3724 oslo_elisabeth MACH_OSLO_ELISABETH OSLO_ELISABETH 3725 tt01 MACH_TT01 TT01 3726 msm8930_cdp MACH_MSM8930_CDP MSM8930_CDP 3727 @@ -1038,6 +3707,7 @@ ptip_murnau MACH_PTIP_MURNAU PTIP_MURNAU 3752 ptip_classic MACH_PTIP_CLASSIC PTIP_CLASSIC 3753 mx53grb MACH_MX53GRB MX53GRB 3754 gagarin MACH_GAGARIN GAGARIN 3755 +msm7627a_qrd1 MACH_MSM7X27A_QRD1 MSM7X27A_QRD1 3756 nas2big MACH_NAS2BIG NAS2BIG 3757 superfemto MACH_SUPERFEMTO SUPERFEMTO 3758 teufel MACH_TEUFEL TEUFEL 3759 @@ -1087,6 +3757,7 @@ ubisys_g1 MACH_UBISYS_G1 UBISYS_G1 3802 mx53_pf1 MACH_MX53_PF1 MX53_PF1 3803 asanti MACH_ASANTI ASANTI 3804 volta MACH_VOLTA VOLTA 3805 +potenza MACH_S5P6450 S5P6450 3806 knight MACH_KNIGHT KNIGHT 3807 beaglebone MACH_BEAGLEBONE BEAGLEBONE 3808 becker MACH_BECKER BECKER 3809 @@ -1148,6 +3819,7 @@ primou MACH_PRIMOU PRIMOU 3864 primoc MACH_PRIMOC PRIMOC 3865 primoct MACH_PRIMOCT PRIMOCT 3866 a9500 MACH_A9500 A9500 3867 +pue_td MACH_PULSE_TD PULSE_TD 3868 pluto MACH_PLUTO PLUTO 3869 acfx100 MACH_ACFX100 ACFX100 3870 msm8625_rumi3 MACH_MSM8625_RUMI3 MSM8625_RUMI3 3871 @@ -1161,6 +3833,8 @@ valente_wx MACH_VALENTE_WX VALENTE_WX 3878 huangshans MACH_HUANGSHANS HUANGSHANS 3879 bosphorus1 MACH_BOSPHORUS1 BOSPHORUS1 3880 prima MACH_PRIMA PRIMA 3881 +meson3_skt MACH_M3_SKT M3_SKT 3882 +meson3_ref MACH_M3_REF M3_REF 3883 evita_ulk MACH_EVITA_ULK EVITA_ULK 3884 merisc600 MACH_MERISC600 MERISC600 3885 dolak MACH_DOLAK DOLAK 3886 @@ -1169,3 +3843,113 @@ elite_ulk MACH_ELITE_ULK ELITE_ULK 3888 pov2 MACH_POV2 POV2 3889 ipod_touch_2g MACH_IPOD_TOUCH_2G IPOD_TOUCH_2G 3890 da850_pqab MACH_DA850_PQAB DA850_PQAB 3891 +fermi MACH_FERMI FERMI 3892 +ccardwmx28 MACH_CCARDWMX28 CCARDWMX28 3893 +ccardmx28 MACH_CCARDMX28 CCARDMX28 3894 +fs20_fcm2050 MACH_FS20_FCM2050 FS20_FCM2050 3895 +kinetis MACH_KINETIS KINETIS 3896 +kai MACH_KAI KAI 3897 +bcthb2 MACH_BCTHB2 BCTHB2 3898 +inels3_cu MACH_INELS3_CU INELS3_CU 3899 +da850_juniper MACH_JUNIPER JUNIPER 3900 +da850_apollo MACH_DA850_APOLLO DA850_APOLLO 3901 +tracnas MACH_TRACNAS TRACNAS 3902 +mityarm335x MACH_MITYARM335X MITYARM335X 3903 +xcgz7x MACH_XCGZ7X XCGZ7X 3904 +cubox MACH_CUBOX CUBOX 3905 +terminator MACH_TERMINATOR TERMINATOR 3906 +eye03 MACH_EYE03 EYE03 3907 +kota3 MACH_KOTA3 KOTA3 3908 +mx53_nitrogen_k MACH_MX5 MX5 3909 +pscpe MACH_PSCPE PSCPE 3910 +akt1100 MACH_AKT1100 AKT1100 3911 +pcaaxl2 MACH_PCAAXL2 PCAAXL2 3912 +primodd_ct MACH_PRIMODD_CT PRIMODD_CT 3913 +nsbc MACH_NSBC NSBC 3914 +meson2_skt MACH_MESON2_SKT MESON2_SKT 3915 +meson2_ref MACH_MESON2_REF MESON2_REF 3916 +ccardwmx28js MACH_CCARDWMX28JS CCARDWMX28JS 3917 +ccardmx28js MACH_CCARDMX28JS CCARDMX28JS 3918 +indico MACH_INDICO INDICO 3919 +msm8960dt MACH_MSM8960DT MSM8960DT 3920 +primods MACH_PRIMODS PRIMODS 3921 +beluga_m1388 MACH_BELUGA_M1388 BELUGA_M1388 3922 +primotd MACH_PRIMOTD PRIMOTD 3923 +varan_master MACH_VARAN_MASTER VARAN_MASTER 3924 +primodd MACH_PRIMODD PRIMODD 3925 +jetduo MACH_JETDUO JETDUO 3926 +mx53_umobo MACH_MX53_UMOBO MX53_UMOBO 3927 +trats MACH_TRATS TRATS 3928 +starcraft MACH_STARCRAFT STARCRAFT 3929 +qseven_tegra2 MACH_QSEVEN_TEGRA2 QSEVEN_TEGRA2 3930 +lichee_sun4i_devbd MACH_LICHEE_SUN4I_DEVBD LICHEE_SUN4I_DEVBD 3931 +movenow MACH_MOVENOW MOVENOW 3932 +golf_u MACH_GOLF_U GOLF_U 3933 +msm7627a_evb MACH_MSM7627A_EVB MSM7627A_EVB 3934 +rambo MACH_RAMBO RAMBO 3935 +golfu MACH_GOLFU GOLFU 3936 +mango310 MACH_MANGO310 MANGO310 3937 +dns343 MACH_DNS343 DNS343 3938 +var_som_om44 MACH_VAR_SOM_OM44 VAR_SOM_OM44 3939 +naon MACH_NAON NAON 3940 +vp4000 MACH_VP4000 VP4000 3941 +impcard MACH_IMPCARD IMPCARD 3942 +smoovcam MACH_SMOOVCAM SMOOVCAM 3943 +cobham3725 MACH_COBHAM3725 COBHAM3725 3944 +cobham3730 MACH_COBHAM3730 COBHAM3730 3945 +cobham3703 MACH_COBHAM3703 COBHAM3703 3946 +quetzal MACH_QUETZAL QUETZAL 3947 +apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948 +apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949 +apq8064_fluid MACH_APQ8064_FLUID APQ8064_FLUID 3950 +apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951 +mango210 MACH_MANGO210 MANGO210 3952 +mango100 MACH_MANGO100 MANGO100 3953 +mango24 MACH_MANGO24 MANGO24 3954 +mango64 MACH_MANGO64 MANGO64 3955 +nsa320 MACH_NSA320 NSA320 3956 +elv_ccu2 MACH_ELV_CCU2 ELV_CCU2 3957 +triton_x00 MACH_TRITON_X00 TRITON_X00 3958 +triton_1500_2000 MACH_TRITON_1500_2000 TRITON_1500_2000 3959 +pogoplugv4 MACH_POGOPLUGV4 POGOPLUGV4 3960 +venus_cl MACH_VENUS_CL VENUS_CL 3961 +vulcano_g20 MACH_VULCANO_G20 VULCANO_G20 3962 +sgs_i9100 MACH_SGS_I9100 SGS_I9100 3963 +stsv2 MACH_STSV2 STSV2 3964 +csb1724 MACH_CSB1724 CSB1724 3965 +omapl138_lcdk MACH_OMAPL138_LCDK OMAPL138_LCDK 3966 +jel_dd MACH_JEWEL_DD JEWEL_DD 3967 +pvd_mx25 MACH_PVD_MX25 PVD_MX25 3968 +meson6_skt MACH_MESON6_SKT MESON6_SKT 3969 +meson6_ref MACH_MESON6_REF MESON6_REF 3970 +pxm MACH_PXM PXM 3971 +stuttgart MACH_S3 S3 3972 +pogoplugv3 MACH_POGOPLUGV3 POGOPLUGV3 3973 +mlp89626 MACH_MLP89626 MLP89626 3974 +iomegahmndce MACH_IOMEGAHMNDCE IOMEGAHMNDCE 3975 +pogoplugv3pci MACH_POGOPLUGV3PCI POGOPLUGV3PCI 3976 +bntv250 MACH_BNTV250 BNTV250 3977 +mx53_qseven MACH_MX53_QSEVEN MX53_QSEVEN 3978 +gtl_it1100 MACH_GTL_IT1100 GTL_IT1100 3979 +mx6q_sabresd MACH_MX6Q_SABRESD MX6Q_SABRESD 3980 +mt4 MACH_MT4 MT4 3981 +jumbo_d MACH_JUMBO_D JUMBO_D 3982 +jumbo_i MACH_JUMBO_I JUMBO_I 3983 +fs20_dmp MACH_FS20_DMP FS20_DMP 3984 +dns320 MACH_DNS320 DNS320 3985 +mx28bacos MACH_MX28BACOS MX28BACOS 3986 +tl80 MACH_TL80 TL80 3987 +polatis_nic_1001 MACH_POLATIS_NIC_1001 POLATIS_NIC_1001 3988 +tely MACH_TELY TELY 3989 +u8520 MACH_U8520 U8520 3990 +manta MACH_MANTA MANTA 3991 +spear1340_lcad MACH_SPEAR_EM_S900 SPEAR_EM_S900 3992 +mpq8064_cdp MACH_MPQ8064_CDP MPQ8064_CDP 3993 +mpq8064_stb MACH_MPQ8064_STB MPQ8064_STB 3994 +mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995 +dm368som MACH_DM368SOM DM368SOM 3996 +gprisb2 MACH_GPRISB2 GPRISB2 3997 +chammid MACH_CHAMMID CHAMMID 3998 +seoul2 MACH_SEOUL2 SEOUL2 3999 +omap4_nooktablet MACH_OMAP4_NOOKTABLET OMAP4_NOOKTABLET 4000 +aalto MACH_AALTO AALTO 4001 |