aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boot/compressed/head.S6
-rw-r--r--arch/arm/configs/android_4430_defconfig1926
-rw-r--r--arch/arm/configs/davinci_all_defconfig2
-rw-r--r--arch/arm/configs/netx_defconfig2
-rw-r--r--arch/arm/configs/omap2plus_defconfig37
-rw-r--r--arch/arm/configs/viper_defconfig2
-rw-r--r--arch/arm/configs/xcep_defconfig2
-rw-r--r--arch/arm/configs/zeus_defconfig2
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h16
-rw-r--r--arch/arm/include/asm/proc-fns.h14
-rw-r--r--arch/arm/kernel/devtree.c3
-rw-r--r--arch/arm/kernel/entry-armv.S6
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/smp.c5
-rw-r--r--arch/arm/kernel/smp_twd.c69
-rw-r--r--arch/arm/kernel/traps.c4
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c2
-rw-r--r--arch/arm/mach-davinci/devices.c2
-rw-r--r--arch/arm/mach-davinci/gpio.c7
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c1
-rw-r--r--arch/arm/mach-footbridge/include/mach/debug-macro.S5
-rw-r--r--arch/arm/mach-msm/timer.c14
-rw-r--r--arch/arm/mach-mxs/ocotp.c2
-rw-r--r--arch/arm/mach-omap1/Makefile7
-rw-r--r--arch/arm/mach-omap1/omap1-cpufreq.c (renamed from arch/arm/plat-omap/cpu-omap.c)54
-rw-r--r--arch/arm/mach-omap1/pm_bus.c8
-rw-r--r--arch/arm/mach-omap2/Kconfig13
-rw-r--r--arch/arm/mach-omap2/Makefile26
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c155
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c3
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c30
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c14
-rw-r--r--arch/arm/mach-omap2/clock.c24
-rw-r--r--arch/arm/mach-omap2/clock.h18
-rw-r--r--arch/arm/mach-omap2/clock34xx.c2
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c1226
-rw-r--r--arch/arm/mach-omap2/clockdomain.c28
-rw-r--r--arch/arm/mach-omap2/clockdomain.h3
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c12
-rw-r--r--arch/arm/mach-omap2/clockdomain44xx.c16
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c204
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h32
-rw-r--r--arch/arm/mach-omap2/common.c1
-rw-r--r--arch/arm/mach-omap2/control.c63
-rw-r--r--arch/arm/mach-omap2/control.h31
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c381
-rw-r--r--arch/arm/mach-omap2/devices.c75
-rw-r--r--arch/arm/mach-omap2/display.c26
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c112
-rw-r--r--arch/arm/mach-omap2/dvfs.c988
-rw-r--r--arch/arm/mach-omap2/dvfs.h38
-rw-r--r--arch/arm/mach-omap2/hsmmc.c7
-rw-r--r--arch/arm/mach-omap2/id.c20
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-wakeupgen.h41
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h102
-rw-r--r--arch/arm/mach-omap2/io.c5
-rw-r--r--arch/arm/mach-omap2/mcbsp.c13
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c30
-rw-r--r--arch/arm/mach-omap2/omap-smp.c32
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c319
-rw-r--r--arch/arm/mach-omap2/omap2plus-cpufreq.c275
-rw-r--r--arch/arm/mach-omap2/omap4-common.c205
-rw-r--r--arch/arm/mach-omap2/omap4-mpuss-lowpower.c526
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h70
-rw-r--r--arch/arm/mach-omap2/omap44xx-smc.S24
-rw-r--r--arch/arm/mach-omap2/omap4_trim_quirks.c78
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c22
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c19
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c19
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c54
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c975
-rw-r--r--arch/arm/mach-omap2/omap_opp_data.h22
-rw-r--r--arch/arm/mach-omap2/omap_pmic.c75
-rw-r--r--arch/arm/mach-omap2/omap_tps6236x.c340
-rw-r--r--arch/arm/mach-omap2/omap_twl.c230
-rw-r--r--arch/arm/mach-omap2/opp.c18
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c81
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c201
-rw-r--r--arch/arm/mach-omap2/pm-debug.c15
-rw-r--r--arch/arm/mach-omap2/pm.c101
-rw-r--r--arch/arm/mach-omap2/pm.h52
-rw-r--r--arch/arm/mach-omap2/pm44xx.c303
-rw-r--r--arch/arm/mach-omap2/powerdomain.c207
-rw-r--r--arch/arm/mach-omap2/powerdomain.h58
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c4
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c76
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c178
-rw-r--r--arch/arm/mach-omap2/prm-regbits-44xx.h18
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c56
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h12
-rw-r--r--arch/arm/mach-omap2/prm44xx.c71
-rw-r--r--arch/arm/mach-omap2/prm44xx.h16
-rw-r--r--arch/arm/mach-omap2/serial.c39
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S486
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c2
-rw-r--r--arch/arm/mach-omap2/smartreflex.c67
-rw-r--r--arch/arm/mach-omap2/smartreflex.h9
-rw-r--r--arch/arm/mach-omap2/sr_device.c11
-rw-r--r--arch/arm/mach-omap2/vc.c454
-rw-r--r--arch/arm/mach-omap2/vc.h70
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c23
-rw-r--r--arch/arm/mach-omap2/vc44xx_data.c32
-rw-r--r--arch/arm/mach-omap2/voltage.c1072
-rw-r--r--arch/arm/mach-omap2/voltage.h192
-rw-r--r--arch/arm/mach-omap2/voltagedomains2xxx_data.c32
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c80
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c121
-rw-r--r--arch/arm/mach-omap2/vp.c329
-rw-r--r--arch/arm/mach-omap2/vp.h133
-rw-r--r--arch/arm/mach-omap2/vp3xxx_data.c35
-rw-r--r--arch/arm/mach-omap2/vp44xx_data.c47
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c1
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c4
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c208
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c6
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c14
-rw-r--r--arch/arm/mach-u300/clock.h2
-rw-r--r--arch/arm/mach-u300/include/mach/u300-regs.h22
-rw-r--r--arch/arm/mach-u300/timer.c3
-rw-r--r--arch/arm/mach-vexpress/v2m.c15
-rw-r--r--arch/arm/mm/context.c20
-rw-r--r--arch/arm/mm/init.c12
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S2
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S2
-rw-r--r--arch/arm/mm/proc-v7.S10
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-dma.c6
-rw-r--r--arch/arm/plat-omap/Kconfig5
-rw-r--r--arch/arm/plat-omap/Makefile4
-rw-r--r--arch/arm/plat-omap/devices.c103
-rw-r--r--arch/arm/plat-omap/i2c.c14
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h2
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h4
-rw-r--r--arch/arm/plat-omap/include/plat/common.h1
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h15
-rw-r--r--arch/arm/plat-omap/include/plat/dsscomp.h23
-rw-r--r--arch/arm/plat-omap/include/plat/gpu.h33
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h12
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h6
-rw-r--r--arch/arm/plat-omap/include/plat/mcpdm.h30
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h5
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h31
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h4
-rw-r--r--arch/arm/plat-omap/include/plat/rpres.h49
-rw-r--r--arch/arm/plat-omap/mcbsp.c88
-rw-r--r--arch/arm/plat-omap/omap-pm-helper.c321
-rw-r--r--arch/arm/plat-omap/omap-pm-helper.h40
-rw-r--r--arch/arm/plat-omap/omap-pm-interface.c239
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c363
-rw-r--r--arch/arm/plat-omap/omap_device.c29
-rw-r--r--arch/arm/plat-omap/omap_rpmsg.c2
154 files changed, 12679 insertions, 3003 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index f9da419..942fad9 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -691,9 +691,9 @@ proc_types:
.word 0x41069260 @ ARM926EJ-S (v5TEJ)
.word 0xff0ffff0
- b __arm926ejs_mmu_cache_on
- b __armv4_mmu_cache_off
- b __armv5tej_mmu_cache_flush
+ W(b) __arm926ejs_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv5tej_mmu_cache_flush
.word 0x00007000 @ ARM7 IDs
.word 0x0000f000
diff --git a/arch/arm/configs/android_4430_defconfig b/arch/arm/configs/android_4430_defconfig
new file mode 100644
index 0000000..d432abe
--- /dev/null
+++ b/arch/arm/configs/android_4430_defconfig
@@ -0,0 +1,1926 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35
+# Fri Sep 3 08:14:37 2010
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_ASHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# TI OMAP Implementations
+#
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2PLUS=y
+# CONFIG_ARCH_OMAP2 is not set
+# CONFIG_ARCH_OMAP3 is not set
+CONFIG_ARCH_OMAP4=y
+
+#
+# OMAP Feature Selections
+#
+CONFIG_OMAP_SMARTREFLEX=y
+# CONFIG_OMAP_SMARTREFLEX_TESTING is not set
+CONFIG_OMAP_SMARTREFLEX_CLASS3=y
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+CONFIG_OMAP_MBOX_FWK=y
+CONFIG_OMAP_REMOTE_PROC=y
+CONFIG_OMAP_RPROC_MEMPOOL_SIZE=0x600000
+CONFIG_OMAP_IOMMU=y
+# CONFIG_OMAP_IOMMU_DEBUG is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+# CONFIG_OMAP_PM is not set
+
+#
+# OMAP Board Type
+#
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_TIWLAN_SDIO is not set
+# CONFIG_OMAP4_ES1 is not set
+CONFIG_MACH_OMAP_4430SDP=y
+CONFIG_MACH_OMAP4_PANDA=y
+# CONFIG_ERRATA_OMAP4_AXI2OCP is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_PL310_ERRATA_588369 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_GIC=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS2,115200n8 initrd=0x81600000,20M ramdisk_size=20480"
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_NVS=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+CONFIG_WAKELOCK=y
+CONFIG_WAKELOCK_STAT=y
+CONFIG_USER_WAKELOCK=y
+CONFIG_EARLYSUSPEND=y
+# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set
+CONFIG_CONSOLE_EARLYSUSPEND=y
+# CONFIG_FB_EARLYSUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+CONFIG_ANDROID_PARANOID_NETWORK=y
+CONFIG_NET_ACTIVITY_STATS=y
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+CONFIG_RPS=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+# CONFIG_BT_L2CAP_EXT_FEATURES is not set
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+# CONFIG_BT_BNEP is not set
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+# CONFIG_RFKILL_PM is not set
+# CONFIG_RFKILL_INPUT is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+CONFIG_ANDROID_PMEM=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_KERNEL_DEBUGGER_CORE=y
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+CONFIG_SENSORS_BH1780=y
+# CONFIG_SENSORS_AK8975 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+CONFIG_UID_STAT=y
+CONFIG_BMP085=y
+# CONFIG_WL127X_RFKILL is not set
+# CONFIG_APANIC is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+CONFIG_KS8851=y
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+CONFIG_INPUT_KEYRESET=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_OMAP4=y
+# CONFIG_KEYBOARD_TWL4030 is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_TOUCHSCREEN_SYNTM12XX=y
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+CONFIG_INPUT_KEYCHORD=y
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
+# CONFIG_INPUT_TWL4030_VIBRA is not set
+# CONFIG_INPUT_TWL6040_VIBRA is not set
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+CONFIG_INPUT_SFH7741=y
+CONFIG_INPUT_CMA3000_I2C=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVMEM=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_TWL4030 is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+CONFIG_TWL6030_BCI_BATTERY=y
+CONFIG_CHARGER_BQ2415x=y
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+CONFIG_SENSORS_LM75=y
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=y
+# CONFIG_TWL4030_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_TWL4030_CODEC is not set
+# CONFIG_MFD_TC35892 is not set
+CONFIG_TWL6030_PWM=y
+CONFIG_TWL6030_GPADC=y
+CONFIG_TWL6040_CODEC=y
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB8500_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
+CONFIG_RC_MAP=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+# CONFIG_IR_IMON is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=y
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_OMAP2_VOUT=y
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_SAA7706H is not set
+# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_DAB is not set
+CONFIG_DMM_OMAP=y
+CONFIG_TILER_OMAP=y
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_TMIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=4
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
+CONFIG_OMAP2_DSS_DPI=y
+# CONFIG_OMAP2_DSS_RFBI is not set
+# CONFIG_OMAP2_DSS_VENC is not set
+CONFIG_OMAP2_DSS_HDMI=y
+CONFIG_OMAP2_DSS_DSI=y
+# CONFIG_OMAP2_DSS_USE_DSI_PLL is not set
+CONFIG_OMAP2_DSS_FAKE_VSYNC=y
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+CONFIG_FB_OMAP2_NUM_FBS=2
+
+#
+# OMAP2/3 Display Device Drivers
+#
+# CONFIG_PANEL_GENERIC is not set
+# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
+# CONFIG_PANEL_SHARP_LQ043T1DG01 is not set
+CONFIG_PANEL_PICO_DLP=y
+CONFIG_PANEL_TAAL=y
+# CONFIG_PANEL_TOPPOLY_TDO35S is not set
+# CONFIG_PANEL_TPO_TD043MTEA1 is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_L4F00242T03 is not set
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+# CONFIG_LCD_S6E63M0 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+# CONFIG_BACKLIGHT_PWM is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_ABE_DSP=y
+CONFIG_SND_OMAP_SOC_MCBSP=y
+CONFIG_SND_OMAP_SOC_MCPDM=y
+CONFIG_SND_OMAP_SOC_ABE=y
+CONFIG_SND_OMAP_SOC_DMIC=y
+CONFIG_SND_OMAP_SOC_SDP4430=y
+CONFIG_SND_OMAP_SOC_HDMI=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_DMIC=y
+CONFIG_SND_SOC_TWL6040=y
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 44xx high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_GADGET_MUSB_HDRC=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_ANDROID is not set
+CONFIG_USB_CDC_COMPOSITE=m
+# CONFIG_USB_G_NOKIA is not set
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_MULTI_RNDIS=y
+CONFIG_USB_G_MULTI_CDC=y
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_TWL4030_USB is not set
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_EMBEDDED_SDIO is not set
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+CONFIG_LEDS_PWM=y
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+# CONFIG_LEDS_TRIGGERS is not set
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+CONFIG_RTC_DRV_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+
+#
+# Android
+#
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_RAM_CONSOLE=y
+CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
+# CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION is not set
+# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set
+CONFIG_ANDROID_TIMED_OUTPUT=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+# CONFIG_POHMELFS is not set
+
+#
+# RAR Register Driver
+#
+CONFIG_IIO=y
+# CONFIG_IIO_RING_BUFFER is not set
+# CONFIG_IIO_TRIGGER is not set
+
+#
+# Accelerometers
+#
+# CONFIG_ADIS16209 is not set
+# CONFIG_ADIS16220 is not set
+# CONFIG_ADIS16240 is not set
+# CONFIG_KXSD9 is not set
+# CONFIG_LIS3L02DQ is not set
+
+#
+# Analog to digital convertors
+#
+# CONFIG_MAX1363 is not set
+
+#
+# Digital gyroscope sensors
+#
+# CONFIG_ADIS16260 is not set
+
+#
+# Inertial measurement units
+#
+# CONFIG_ADIS16300 is not set
+# CONFIG_ADIS16350 is not set
+# CONFIG_ADIS16400 is not set
+
+#
+# Light sensors
+#
+# CONFIG_SENSORS_TSL2563 is not set
+
+#
+# Magnetometer sensors
+#
+CONFIG_SENSORS_HMC5843=y
+
+#
+# Triggers - standalone
+#
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_FB_SM7XX is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+CONFIG_TI_ST=m
+CONFIG_ST_BT=m
+CONFIG_ST_FM=m
+# CONFIG_ADIS16255 is not set
+CONFIG_Sys_Link=y
+CONFIG_SYSLINK_PROC=y
+CONFIG_SYSLINK_PROC4430=y
+CONFIG_DUCATI_BASEIMAGE_PHYS_ADDR=0x9CF00000
+CONFIG_SYSLINK_DUCATI_PM=y
+CONFIG_OMAP_DEVICE_HANDLER=y
+CONFIG_MPU_SYSLINK_PLATFORM=y
+CONFIG_MPU_SYSLINK_IPC=y
+CONFIG_SYSLINK_USE_SYSMGR=y
+CONFIG_SYSLINK_IOMMU_ENABLE=y
+CONFIG_SYSLINK_RECOVERY=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 889922a..67b5abb6 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -157,7 +157,7 @@ CONFIG_LEDS_GPIO=m
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_XFS_FS=m
diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig
index 316af54..9c0ad79 100644
--- a/arch/arm/configs/netx_defconfig
+++ b/arch/arm/configs/netx_defconfig
@@ -60,7 +60,7 @@ CONFIG_FB_ARMCLCD=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
CONFIG_INOTIFY=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index d5f00d7..5708151 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -8,7 +8,6 @@ CONFIG_LOG_BUF_SHIFT=16
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -21,6 +20,8 @@ CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_ARCH_OMAP=y
+CONFIG_OMAP_SMARTREFLEX=y
+CONFIG_OMAP_SMARTREFLEX_CLASS3=y
CONFIG_OMAP_RESET_CLOCKS=y
CONFIG_OMAP_MUX_DEBUG=y
CONFIG_ARM_THUMBEE=y
@@ -34,6 +35,14 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_HOTPLUG=y
+CONFIG_CPU_IDLE=y
CONFIG_FPE_NWFPE=y
CONFIG_BINFMT_MISC=y
CONFIG_PM_DEBUG=y
@@ -64,6 +73,8 @@ CONFIG_MAC80211=m
CONFIG_MAC80211_RC_PID=y
CONFIG_MAC80211_RC_DEFAULT_PID=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
CONFIG_CONNECTOR=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
@@ -219,13 +230,33 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_PROVE_LOCKING=y
+CONFIG_SPARSE_RCU_POINTER=y
+CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=120
+CONFIG_DEBUG_PER_CPU_MAPS=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
CONFIG_SECURITY=y
CONFIG_CRYPTO_MICHAEL_MIC=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index 8b0c717..1d01ddd 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -142,7 +142,7 @@ CONFIG_USB_GADGETFS=m
CONFIG_USB_FILE_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_SA1100=m
CONFIG_EXT2_FS=m
diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig
index 5b55041..721832f 100644
--- a/arch/arm/configs/xcep_defconfig
+++ b/arch/arm/configs/xcep_defconfig
@@ -73,7 +73,7 @@ CONFIG_SENSORS_MAX6650=m
# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_SA1100=m
CONFIG_DMADEVICES=y
# CONFIG_DNOTIFY is not set
diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig
index 960f655..59577ad 100644
--- a/arch/arm/configs/zeus_defconfig
+++ b/arch/arm/configs/zeus_defconfig
@@ -158,7 +158,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_ISL1208=m
CONFIG_RTC_DRV_PXA=m
CONFIG_EXT2_FS=y
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 16bd480..8dee14a 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -45,23 +45,25 @@
#define L2X0_CLEAN_INV_LINE_PA 0x7F0
#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
#define L2X0_CLEAN_INV_WAY 0x7FC
-#define L2X0_LOCKDOWN_WAY_D 0x900
-#define L2X0_LOCKDOWN_WAY_I 0x904
+#define L2X0_LOCKDOWN_WAY_D0 0x900
+#define L2X0_LOCKDOWN_WAY_D1 0x908
+#define L2X0_LOCKDOWN_WAY_I0 0x904
+#define L2X0_LOCKDOWN_WAY_I1 0x90C
#define L2X0_TEST_OPERATION 0xF00
#define L2X0_LINE_DATA 0xF10
#define L2X0_LINE_TAG 0xF30
#define L2X0_DEBUG_CTRL 0xF40
#define L2X0_PREFETCH_CTRL 0xF60
#define L2X0_POWER_CTRL 0xF80
-#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
-#define L2X0_STNDBY_MODE_EN (1 << 0)
+#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
+#define L2X0_STNDBY_MODE_EN (1 << 0)
/* Registers shifts and masks */
#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
#define L2X0_CACHE_ID_PART_L210 (1 << 6)
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
-#define L2X0_AUX_CTRL_MASK 0xc0000fff
+#define L2X0_AUX_CTRL_MASK 0xd0000fff
#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17)
@@ -72,6 +74,10 @@
#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
+#define L2X0_PREFETCH_DATA_PREFETCH_SHIFT 28
+#define L2X0_PREFETCH_INTSTR_PREFETCH_SHIFT 29
+#define L2X0_PREFETCH_DOUBLE_LINEFILL_SHIFT 30
+
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8ec535e..35c3fc9 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -97,8 +97,22 @@ extern void cpu_resume(void);
#ifdef CONFIG_MMU
+#ifdef CONFIG_SMP
+
+#define cpu_switch_mm(pgd, mm) \
+ ({ \
+ unsigned long flags; \
+ local_irq_save(flags); \
+ cpu_do_switch_mm(virt_to_phys(pgd), mm); \
+ local_irq_restore(flags); \
+ })
+
+#else /* SMP */
+
#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
+#endif
+
#define cpu_get_pgd() \
({ \
unsigned long pg; \
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index a701e42..0cdd7b4 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -76,6 +76,9 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
unsigned long dt_root;
const char *model;
+ if (!dt_phys)
+ return NULL;
+
devtree = phys_to_virt(dt_phys);
/* check device tree validity */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index e8d8856..90c62cd 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -435,6 +435,10 @@ __irq_usr:
usr_entry
kuser_cmpxchg_check
+#ifdef CONFIG_IRQSOFF_TRACER
+ bl trace_hardirqs_off
+#endif
+
get_thread_info tsk
#ifdef CONFIG_PREEMPT
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -453,7 +457,7 @@ __irq_usr:
#endif
mov why, #0
- b ret_to_user
+ b ret_to_user_from_irq
UNWIND(.fnend )
ENDPROC(__irq_usr)
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 1e7b04a..b2a27b6 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -64,6 +64,7 @@ work_resched:
ENTRY(ret_to_user)
ret_slow_syscall:
disable_irq @ disable interrupts
+ENTRY(ret_to_user_from_irq)
ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK
bne work_pending
@@ -75,6 +76,7 @@ no_work_pending:
arch_ret_to_user r1, lr
restore_user_regs fast = 0, offset = 0
+ENDPROC(ret_to_user_from_irq)
ENDPROC(ret_to_user)
/*
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 344e52b..e64ed87 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -278,6 +278,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();
+ static bool booted;
printk("CPU%u: Booted secondary processor\n", cpu);
@@ -313,7 +314,9 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
*/
percpu_timer_setup();
- calibrate_delay();
+ if (!booted)
+ calibrate_delay();
+ booted = true;
smp_store_cpu_info(cpu);
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 60636f4..dbf58d4 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -10,21 +10,29 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/err.h>
#include <linux/smp.h>
#include <linux/jiffies.h>
#include <linux/clockchips.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/percpu.h>
#include <asm/smp_twd.h>
#include <asm/hardware/gic.h>
+#define TWD_MIN_RANGE 4
+
/* set up by the platform code */
void __iomem *twd_base;
+static struct clk *twd_clk;
static unsigned long twd_timer_rate;
+static DEFINE_PER_CPU(struct clock_event_device *, twd_ce);
static void twd_set_mode(enum clock_event_mode mode,
struct clock_event_device *clk)
@@ -80,6 +88,49 @@ int twd_timer_ack(void)
return 0;
}
+/*
+ * Updates clockevent frequency when the cpu frequency changes.
+ * Called on the cpu that is changing frequency with interrupts disabled.
+ */
+static void twd_update_frequency(void *data)
+{
+ twd_timer_rate = clk_get_rate(twd_clk);
+
+ clockevents_reconfigure(__get_cpu_var(twd_ce), twd_timer_rate,
+ TWD_MIN_RANGE);
+}
+
+static int twd_cpufreq_transition(struct notifier_block *nb,
+ unsigned long state, void *data)
+{
+ struct cpufreq_freqs *freqs = data;
+
+ /*
+ * The twd clock events must be reprogrammed to account for the new
+ * frequency. The timer is local to a cpu, so cross-call to the
+ * changing cpu.
+ */
+ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
+ smp_call_function_single(freqs->cpu, twd_update_frequency,
+ NULL, 1);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block twd_cpufreq_nb = {
+ .notifier_call = twd_cpufreq_transition,
+};
+
+static int twd_cpufreq_init(void)
+{
+ if (!IS_ERR_OR_NULL(twd_clk))
+ return cpufreq_register_notifier(&twd_cpufreq_nb,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ return 0;
+}
+core_initcall(twd_cpufreq_init);
+
static void __cpuinit twd_calibrate_rate(void)
{
unsigned long count;
@@ -124,7 +175,16 @@ static void __cpuinit twd_calibrate_rate(void)
*/
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
- twd_calibrate_rate();
+ if (twd_clk == NULL) {
+ twd_clk = clk_get_sys("smp_twd", NULL);
+ if (IS_ERR_OR_NULL(twd_clk))
+ pr_warn("%s: no clock found\n", __func__);
+ }
+
+ if (!IS_ERR_OR_NULL(twd_clk))
+ twd_timer_rate = clk_get_rate(twd_clk);
+ else
+ twd_calibrate_rate();
clk->name = "local_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
@@ -132,13 +192,16 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clk->rating = 350;
clk->set_mode = twd_set_mode;
clk->set_next_event = twd_set_next_event;
- clk->shift = 20;
- clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift);
+
+ clockevents_calc_mult_shift(clk, twd_timer_rate, TWD_MIN_RANGE);
+
clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
/* Make sure our local interrupt controller has this enabled */
gic_enable_ppi(clk->irq);
+ __get_cpu_var(twd_ce) = clk;
+
clockevents_register_device(clk);
}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d52eec2..6807cb1 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -139,7 +139,7 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
fs = get_fs();
set_fs(KERNEL_DS);
- for (i = -4; i < 1; i++) {
+ for (i = -4; i < 1 + !!thumb; i++) {
unsigned int val, bad;
if (thumb)
@@ -563,7 +563,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
if (!pmd_present(*pmd))
goto bad_access;
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
- if (!pte_present(*pte) || !pte_dirty(*pte)) {
+ if (!pte_present(*pte) || !pte_write(*pte) || !pte_dirty(*pte)) {
pte_unmap_unlock(pte, ptl);
goto bad_access;
}
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 4e66881..fc4e98e 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -494,7 +494,7 @@ static struct platform_device da850_mcasp_device = {
.resource = da850_mcasp_resources,
};
-struct platform_device davinci_pcm_device = {
+static struct platform_device davinci_pcm_device = {
.name = "davinci-pcm-audio",
.id = -1,
};
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 8f4f736..806a2f0 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -298,7 +298,7 @@ static void davinci_init_wdt(void)
/*-------------------------------------------------------------------------*/
-struct platform_device davinci_pcm_device = {
+static struct platform_device davinci_pcm_device = {
.name = "davinci-pcm-audio",
.id = -1,
};
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index a0b8388..e722139 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -252,9 +252,11 @@ static struct irq_chip gpio_irqchip = {
static void
gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct davinci_gpio_regs __iomem *g = irq2regs(irq);
+ struct davinci_gpio_regs __iomem *g;
u32 mask = 0xffff;
+ g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
+
/* we only care about one bank */
if (irq & 1)
mask <<= 16;
@@ -422,8 +424,7 @@ static int __init davinci_gpio_irq_setup(void)
/* set up all irqs in this bank */
irq_set_chained_handler(bank_irq, gpio_irq_handler);
- irq_set_chip_data(bank_irq, (__force void *)g);
- irq_set_handler_data(bank_irq, (void *)irq);
+ irq_set_handler_data(bank_irq, (__force void *)g);
for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
irq_set_chip(irq, &gpio_irqchip);
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index 5f1f986..121ad1d 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -103,6 +103,7 @@ static void __init footbridge_timer_init(void)
clockevents_calc_mult_shift(ce, mem_fclk_21285, 5);
ce->max_delta_ns = clockevent_delta2ns(0xffffff, ce);
ce->min_delta_ns = clockevent_delta2ns(0x000004, ce);
+ ce->cpumask = cpumask_of(smp_processor_id());
clockevents_register_device(ce);
}
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S
index 30b971d..1be2eeb 100644
--- a/arch/arm/mach-footbridge/include/mach/debug-macro.S
+++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S
@@ -26,6 +26,7 @@
#include <asm/hardware/debug-8250.S>
#else
+#include <mach/hardware.h>
/* For EBSA285 debugging */
.equ dc21285_high, ARMCSR_BASE & 0xff000000
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
@@ -36,8 +37,8 @@
.else
mov \rp, #0
.endif
- orr \rv, \rp, #0x42000000
- orr \rp, \rp, #dc21285_high
+ orr \rv, \rp, #dc21285_high
+ orr \rp, \rp, #0x42000000
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 38b95e9..63621f1 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -23,6 +23,8 @@
#include <linux/io.h>
#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+
#include <mach/msm_iomap.h>
#include <mach/cpu.h>
@@ -55,10 +57,12 @@ enum timer_location {
#if defined(CONFIG_ARCH_QSD8X50)
#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
#define MSM_DGT_SHIFT (0)
-#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) || \
- defined(CONFIG_ARCH_MSM8960)
+#elif defined(CONFIG_ARCH_MSM7X30)
#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
#define MSM_DGT_SHIFT (0)
+#elif defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
+#define DGT_HZ (27000000 / 4) /* 27 MHz (PXO) / 4 by default */
+#define MSM_DGT_SHIFT (0)
#else
#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
#define MSM_DGT_SHIFT (5)
@@ -100,7 +104,11 @@ static cycle_t msm_read_timer_count(struct clocksource *cs)
{
struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource);
- return readl(clk->global_counter);
+ /*
+ * Shift timer count down by a constant due to unreliable lower bits
+ * on some targets.
+ */
+ return readl(clk->global_counter) >> clk->shift;
}
static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt)
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index 65157a3..54add60 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -16,6 +16,8 @@
#include <linux/err.h>
#include <linux/mutex.h>
+#include <asm/processor.h> /* for cpu_relax() */
+
#include <mach/mxs.h>
#define OCOTP_WORD_OFFSET 0x20
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index af98117..9600410 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -4,14 +4,17 @@
# Common support
obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
-obj-y += clock.o clock_data.o opp_data.o reset.o
+obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
+# CPUFREQ driver
+obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o
+
# Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
+obj-$(CONFIG_PM) += pm.o sleep.o
# DSP
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/mach-omap1/omap1-cpufreq.c
index da4f68d..7c5216e 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/mach-omap1/omap1-cpufreq.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/plat-omap/cpu-omap.c
+ * OMAP1 cpufreq driver
*
* CPU frequency scaling for OMAP
*
@@ -8,6 +8,9 @@
*
* Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
*
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.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.
@@ -21,25 +24,20 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/opp.h>
-#include <mach/hardware.h>
-#include <plat/clock.h>
#include <asm/system.h>
-#define VERY_HI_RATE 900000000
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
-static struct cpufreq_frequency_table *freq_table;
+#include <mach/hardware.h>
-#ifdef CONFIG_ARCH_OMAP1
-#define MPU_CLK "mpu"
-#else
-#define MPU_CLK "virt_prcm_set"
-#endif
+#define VERY_HI_RATE 900000000
+static struct cpufreq_frequency_table *freq_table;
static struct clk *mpu_clk;
-/* TODO: Add support for SDRAM timing changes */
-
static int omap_verify_speed(struct cpufreq_policy *policy)
{
if (freq_table)
@@ -91,21 +89,22 @@ static int omap_target(struct cpufreq_policy *policy,
return ret;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
#ifdef CONFIG_CPU_FREQ_DEBUG
- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
- freqs.old, freqs.new);
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
#endif
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
}
-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+static int __init omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
- mpu_clk = clk_get(NULL, MPU_CLK);
+ mpu_clk = clk_get(NULL, "mpu");
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
@@ -115,6 +114,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
policy->cur = policy->min = policy->max = omap_getspeed(0);
clk_init_cpufreq_table(&freq_table);
+
if (freq_table) {
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
@@ -126,6 +126,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
VERY_HI_RATE) / 1000;
}
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(0);
+
/* FIXME: what's the actual transition time? */
policy->cpuinfo.transition_latency = 300 * 1000;
@@ -151,7 +155,7 @@ static struct cpufreq_driver omap_driver = {
.get = omap_getspeed,
.init = omap_cpu_init,
.exit = omap_cpu_exit,
- .name = "omap",
+ .name = "omap1",
.attr = omap_cpufreq_attr,
};
@@ -160,12 +164,12 @@ static int __init omap_cpufreq_init(void)
return cpufreq_register_driver(&omap_driver);
}
-arch_initcall(omap_cpufreq_init);
-
-/*
- * if ever we want to remove this, upon cleanup call:
- *
- * cpufreq_unregister_driver()
- * cpufreq_frequency_table_put_attr()
- */
+static void __exit omap_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&omap_driver);
+}
+MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs");
+MODULE_LICENSE("GPL");
+module_init(omap_cpufreq_init);
+module_exit(omap_cpufreq_exit);
diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
index fe31d93..334fb88 100644
--- a/arch/arm/mach-omap1/pm_bus.c
+++ b/arch/arm/mach-omap1/pm_bus.c
@@ -56,9 +56,13 @@ static struct dev_power_domain default_power_domain = {
USE_PLATFORM_PM_SLEEP_OPS
},
};
+#define OMAP1_PWR_DOMAIN (&default_power_domain)
+#else
+#define OMAP1_PWR_DOMAIN NULL
+#endif /* CONFIG_PM_RUNTIME */
static struct pm_clk_notifier_block platform_bus_notifier = {
- .pwr_domain = &default_power_domain,
+ .pwr_domain = OMAP1_PWR_DOMAIN,
.con_ids = { "ick", "fck", NULL, },
};
@@ -72,4 +76,4 @@ static int __init omap1_pm_runtime_init(void)
return 0;
}
core_initcall(omap1_pm_runtime_init);
-#endif /* CONFIG_PM_RUNTIME */
+
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 19d5891..ef7e12f 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -314,6 +314,7 @@ config MACH_OMAP_4430SDP
select OMAP_PACKAGE_CBL
select OMAP_PACKAGE_CBS
select REGULATOR_FIXED_VOLTAGE
+ select OMAP_TPS6236X
config MACH_OMAP4_PANDA
bool "OMAP4 Panda Board"
@@ -342,6 +343,18 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is
going on could result in system crashes;
+config OMAP_TPS6236X
+ bool
+
+config OMAP_ALLOW_OSWR
+ bool "Enable Open Switch Retention"
+ depends on ARCH_OMAP4
+ default n
+ help
+ Select this option to enable OSWR support.
+ Which means the Logic of power domains can be lost now
+ unlike the CSWR wherein the logic is retained
+
endmenu
endif
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index a05bcff..07c5d28 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,7 +4,7 @@
# Common support
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
- common.o gpio.o dma.o wd_timer.o
+ common.o gpio.o dma.o wd_timer.o omap_pmic.o
omap-2-3-common = irq.o sdrc.o
hwmod-common = omap_hwmod.o \
@@ -19,12 +19,14 @@ obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common)
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+obj-$(CONFIG_OMAP_TPS6236X) += omap_tps6236x.o
# SMP support ONLY available for OMAP4
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
-obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o
+obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o \
+ omap-wakeupgen.o
plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -56,19 +58,25 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
endif
+# CPUFREQ driver
+obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o
+
# Power Management
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o \
+ omap4-mpuss-lowpower.o sleep44xx.o \
+ cpuidle44xx.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
AFLAGS_sleep24xx.o :=-Wa,-march=armv6
AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec)
ifeq ($(CONFIG_PM_VERBOSE),y)
CFLAGS_pm_bus.o += -DDEBUG
@@ -79,19 +87,20 @@ endif
# PRCM
obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
- vc3xxx_data.o vp3xxx_data.o
+ vc3xxx_data.o vp3xxx_data.o dvfs.o
# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
# will be removed once the OMAP4 part of the codebase is converted to
# use OMAP4-specific PRCM functions.
obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
cm44xx.o prcm_mpu44xx.o \
prminst44xx.o vc44xx_data.o \
- vp44xx_data.o
+ vp44xx_data.o dvfs.o
# OMAP voltage domains
ifeq ($(CONFIG_PM),y)
-voltagedomain-common := voltage.o
-obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
+voltagedomain-common := voltage.o vc.o vp.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) \
+ voltagedomains2xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \
voltagedomains3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \
@@ -157,6 +166,9 @@ obj-$(CONFIG_OMAP3_EMU) += emu.o
obj-$(CONFIG_ARCH_OMAP3) += omap_l3_smx.o
obj-$(CONFIG_ARCH_OMAP4) += omap_l3_noc.o
+# LDO stuff
+obj-$(CONFIG_ARCH_OMAP4) += omap4_trim_quirks.o
+
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 63de2d3..541ca0e 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -37,12 +37,14 @@
#include <plat/mmc.h>
#include <plat/omap4-keypad.h>
#include <video/omapdss.h>
+#include <video/omap-panel-nokia-dsi.h>
#include "mux.h"
#include "hsmmc.h"
#include "timer-gp.h"
#include "control.h"
#include "common-board-devices.h"
+#include "pm.h"
#define ETH_KS8851_IRQ 34
#define ETH_KS8851_POWER_ON 48
@@ -51,6 +53,13 @@
#define OMAP4_SFH7741_ENABLE_GPIO 188
#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define LCD_BL_GPIO 27 /* LCD Backlight GPIO */
+/* PWM2 and TOGGLE3 register offsets */
+#define LED_PWM2ON 0x03
+#define LED_PWM2OFF 0x04
+#define TWL6030_TOGGLE3 0x92
+
+#define TPS62361_GPIO 7
static const int sdp4430_keymap[] = {
KEY(0, 0, KEY_E),
@@ -271,24 +280,13 @@ static int __init omap_ethernet_init(void)
return status;
}
-static struct platform_device sdp4430_lcd_device = {
- .name = "sdp4430_lcd",
- .id = -1,
-};
-
static struct platform_device *sdp4430_devices[] __initdata = {
- &sdp4430_lcd_device,
&sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
&sdp4430_leds_pwm,
};
-static struct omap_lcd_config sdp4430_lcd_config __initdata = {
- .ctrl_name = "internal",
-};
-
static struct omap_board_config_kernel sdp4430_config[] __initdata = {
- { OMAP_TAG_LCD, &sdp4430_lcd_config },
};
static void __init omap_4430sdp_init_early(void)
@@ -344,6 +342,10 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
.dev_name = "omap_hsmmc.0",
},
};
+static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
@@ -490,7 +492,10 @@ static struct regulator_init_data sdp4430_vcxio = {
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
+ .always_on = true,
},
+ .num_consumer_supplies = ARRAY_SIZE(sdp4430_vcxio_supply),
+ .consumer_supplies = sdp4430_vcxio_supply,
};
static struct regulator_init_data sdp4430_vdac = {
@@ -576,6 +581,76 @@ static void __init omap_sfh7741prox_init(void)
__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
}
+static int dsi1_panel_set_backlight(struct omap_dss_device *dssdev, int level)
+{
+ int r;
+
+ r = twl_i2c_write_u8(TWL_MODULE_PWM, 0x7F, LED_PWM2OFF);
+ if (r)
+ return r;
+
+ if (level > 1) {
+ if (level == 255)
+ level = 0x7F;
+ else
+ level = (~(level/2)) & 0x7F;
+
+ r = twl_i2c_write_u8(TWL_MODULE_PWM, level, LED_PWM2ON);
+ if (r)
+ return r;
+ r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x30, TWL6030_TOGGLE3);
+ if (r)
+ return r;
+ } else if (level <= 1) {
+ r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x08, TWL6030_TOGGLE3);
+ if (r)
+ return r;
+ r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x28, TWL6030_TOGGLE3);
+ if (r)
+ return r;
+ r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x00, TWL6030_TOGGLE3);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
+static struct nokia_dsi_panel_data dsi1_panel;
+
+static void sdp4430_lcd_init(void)
+{
+ u32 reg;
+ int status;
+
+ /* Enable 3 lanes in DSI1 module, disable pull down */
+ reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
+ reg &= ~OMAP4_DSI1_LANEENABLE_MASK;
+ reg |= 0x7 << OMAP4_DSI1_LANEENABLE_SHIFT;
+ reg &= ~OMAP4_DSI1_PIPD_MASK;
+ reg |= 0x7 << OMAP4_DSI1_PIPD_SHIFT;
+ omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
+
+ /* Panel Taal reset and backlight GPIO init */
+ status = gpio_request_one(dsi1_panel.reset_gpio, GPIOF_DIR_OUT,
+ "lcd_reset_gpio");
+ if (status)
+ pr_err("%s: Could not get lcd_reset_gpio\n", __func__);
+
+ if (dsi1_panel.use_ext_te) {
+ status = omap_mux_init_signal("gpmc_ncs4.gpio_101",
+ OMAP_PIN_INPUT_PULLUP);
+ if (status)
+ pr_err("%s: Could not get ext_te gpio\n", __func__);
+ }
+
+ status = gpio_request_one(LCD_BL_GPIO, GPIOF_DIR_OUT, "lcd_bl_gpio");
+ if (status)
+ pr_err("%s: Could not get lcd_bl_gpio\n", __func__);
+
+ gpio_set_value(LCD_BL_GPIO, 0);
+}
+
static void sdp4430_hdmi_mux_init(void)
{
/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
@@ -613,6 +688,52 @@ static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
gpio_free(HDMI_GPIO_HPD);
}
+static struct nokia_dsi_panel_data dsi1_panel = {
+ .name = "taal",
+ .reset_gpio = 102,
+ .use_ext_te = false,
+ .ext_te_gpio = 101,
+ .esd_interval = 0,
+ .set_backlight = dsi1_panel_set_backlight,
+};
+
+static struct omap_dss_device sdp4430_lcd_device = {
+ .name = "lcd",
+ .driver_name = "taal",
+ .type = OMAP_DISPLAY_TYPE_DSI,
+ .data = &dsi1_panel,
+ .phy.dsi = {
+ .clk_lane = 1,
+ .clk_pol = 0,
+ .data1_lane = 2,
+ .data1_pol = 0,
+ .data2_lane = 3,
+ .data2_pol = 0,
+ },
+
+ .clocks = {
+ .dispc = {
+ .channel = {
+ .lck_div = 1, /* Logic Clock = 172.8 MHz */
+ .pck_div = 5, /* Pixel Clock = 34.56 MHz */
+ .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
+ },
+ .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
+ },
+
+ .dsi = {
+ .regn = 16, /* Fint = 2.4 MHz */
+ .regm = 180, /* DDR Clock = 216 MHz */
+ .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
+ .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
+
+ .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
+ .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
+ },
+ },
+ .channel = OMAP_DSS_CHANNEL_LCD,
+};
+
static struct omap_dss_device sdp4430_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
@@ -632,17 +753,19 @@ static struct omap_dss_device sdp4430_hdmi_device = {
};
static struct omap_dss_device *sdp4430_dss_devices[] = {
+ &sdp4430_lcd_device,
&sdp4430_hdmi_device,
};
static struct omap_dss_board_info sdp4430_dss_data = {
.num_devices = ARRAY_SIZE(sdp4430_dss_devices),
.devices = sdp4430_dss_devices,
- .default_device = &sdp4430_hdmi_device,
+ .default_device = &sdp4430_lcd_device,
};
void omap_4430sdp_display_init(void)
{
+ sdp4430_lcd_init();
sdp4430_hdmi_mux_init();
omap_display_init(&sdp4430_dss_data);
}
@@ -757,6 +880,14 @@ static void __init omap_4430sdp_init(void)
pr_err("Keypad initialization failed: %d\n", status);
omap_4430sdp_display_init();
+
+ if (cpu_is_omap446x()) {
+ /* Vsel0 = gpio, vsel1 = gnd */
+ status = omap_tps6236x_board_setup(true, TPS62361_GPIO, -1,
+ OMAP_PIN_OFF_OUTPUT_HIGH, -1);
+ if (status)
+ pr_err("TPS62361 initialization failed: %d\n", status);
+ }
}
static void __init omap_4430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 2a0bb48..23f71d4 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -84,7 +84,8 @@ static struct mtd_partition omap3pandora_nand_partitions[] = {
static struct omap_nand_platform_data pandora_nand_data = {
.cs = 0,
- .devsize = 1, /* '0' for 8-bit, '1' for 16-bit device */
+ .devsize = NAND_BUSWIDTH_16,
+ .xfer_type = NAND_OMAP_PREFETCH_DMA,
.parts = omap3pandora_nand_partitions,
.nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions),
};
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 0cfe200..10ce8d0 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -380,6 +380,24 @@ static struct regulator_init_data omap4_panda_clk32kg = {
},
};
+static void omap4_audio_conf(void)
+{
+ /* twl6040 naudint */
+ omap_mux_init_signal("sys_nirq2.sys_nirq2", \
+ OMAP_PIN_INPUT_PULLUP);
+}
+
+static struct twl4030_codec_audio_data twl6040_audio = {
+ /* Add audio only data */
+};
+
+static struct twl4030_codec_data twl6040_codec = {
+ .audio = &twl6040_audio,
+ .audpwron_gpio = 127,
+ .naudint_irq = OMAP44XX_IRQ_SYS_2N,
+ .irq_base = TWL6040_CODEC_IRQ_BASE,
+};
+
static struct twl4030_platform_data omap4_panda_twldata = {
.irq_base = TWL6030_IRQ_BASE,
.irq_end = TWL6030_IRQ_END,
@@ -395,6 +413,9 @@ static struct twl4030_platform_data omap4_panda_twldata = {
.vaux3 = &omap4_panda_vaux3,
.clk32kg = &omap4_panda_clk32kg,
.usb = &omap4_usbphy_data,
+
+ /* children */
+ .codec = &twl6040_codec,
};
/*
@@ -693,8 +714,15 @@ static void __init omap4_panda_init(void)
pr_err("error setting wl12xx data\n");
omap4_panda_i2c_init();
+ omap4_audio_conf();
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
- platform_device_register(&omap_vwlan_device);
+/*
+ * This is temporaray. With WLAN regsitering, we see that UART2 is not
+ * idling on panda and CORE RET is not happening. So removing this FTM.
+ * Later will be enabled.
+ *
+ * platform_device_register(&omap_vwlan_device);
+ */
board_serial_init();
omap4_twl6030_hsmmc_init(mmc);
omap4_ehci_init();
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index bcffee0..a7e78e4 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -292,12 +292,14 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
for (n = dd->min_divider; n <= dd->max_divider; n++) {
- /* Is the (input clk, divider) pair valid for the DPLL? */
- r = _dpll_test_fint(clk, n);
- if (r == DPLL_FINT_UNDERFLOW)
- break;
- else if (r == DPLL_FINT_INVALID)
- continue;
+ if (cpu_is_omap34xx()) {
+ /* Is the (input clk, divider)pair valid for the DPLL?*/
+ r = _dpll_test_fint(clk, n);
+ if (r == DPLL_FINT_UNDERFLOW)
+ break;
+ else if (r == DPLL_FINT_INVALID)
+ continue;
+ }
/* Compute the scaled DPLL multiplier, based on the divider */
m = scaled_rt_rp * n;
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 180299e..1334f59 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -32,6 +32,7 @@
#include "clock.h"
#include "cm2xxx_3xxx.h"
+#include "cm44xx.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
@@ -43,6 +44,11 @@ u8 cpu_mask;
/* Private functions */
+static void _omap4_module_wait_ready(struct clk *clk)
+{
+ omap4_cm_wait_module_ready(clk->enable_reg);
+}
+
/**
* _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
* @clk: struct clk * belonging to the module
@@ -190,8 +196,12 @@ int omap2_dflt_clk_enable(struct clk *clk)
__raw_writel(v, clk->enable_reg);
v = __raw_readl(clk->enable_reg); /* OCP barrier */
- if (clk->ops->find_idlest)
- _omap2_module_wait_ready(clk);
+ if (clk->ops->find_idlest) {
+ if (cpu_is_omap44xx())
+ _omap4_module_wait_ready(clk);
+ else
+ _omap2_module_wait_ready(clk);
+ }
return 0;
}
@@ -219,6 +229,12 @@ void omap2_dflt_clk_disable(struct clk *clk)
/* No OCP barrier needed here since it is a disable operation */
}
+const struct clkops clkops_omap4_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+};
+
const struct clkops clkops_omap2_dflt_wait = {
.enable = omap2_dflt_clk_enable,
.disable = omap2_dflt_clk_disable,
@@ -327,6 +343,10 @@ int omap2_clk_enable(struct clk *clk)
}
}
+ /* If clockdomain supports hardware control, enable it */
+ if (clk->clkdm)
+ clkdm_allow_idle(clk->clkdm);
+
return 0;
oce_err3:
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index e10ff2b..bfc8725 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -64,6 +64,9 @@ void omap3_noncore_dpll_disable(struct clk *clk);
int omap4_dpllmx_gatectrl_read(struct clk *clk);
void omap4_dpllmx_allow_gatectrl(struct clk *clk);
void omap4_dpllmx_deny_gatectrl(struct clk *clk);
+int omap4460_mpu_dpll_set_rate(struct clk *clk, unsigned long rate);
+long omap4460_mpu_dpll_round_rate(struct clk *clk, unsigned long rate);
+unsigned long omap4460_mpu_dpll_recalc(struct clk *clk);
#ifdef CONFIG_OMAP_RESET_CLOCKS
void omap2_clk_disable_unused(struct clk *clk);
@@ -132,6 +135,7 @@ extern u8 cpu_mask;
extern const struct clkops clkops_omap2_dflt_wait;
extern const struct clkops clkops_dummy;
extern const struct clkops clkops_omap2_dflt;
+extern const struct clkops clkops_omap4_dflt_wait;
extern struct clk_functions omap2_clk_functions;
extern struct clk *vclk, *sclk;
@@ -141,7 +145,9 @@ extern const struct clksel_rate gpt_sys_rates[];
extern const struct clksel_rate gfx_l3_rates[];
extern const struct clksel_rate dsp_ick_rates[];
-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
+#ifdef CONFIG_CPU_FREQ
+
+#ifdef CONFIG_ARCH_OMAP2
extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
#else
@@ -149,6 +155,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
#define omap2_clk_exit_cpufreq_table 0
#endif
+#ifdef CONFIG_ARCH_OMAP3
+extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#else
+#define omap3_clk_init_cpufreq_table 0
+#define omap3_clk_exit_cpufreq_table 0
+#endif
+
+#endif /* CONFIG_CPU_FREQ */
+
extern const struct clkops clkops_omap2_iclk_dflt_wait;
extern const struct clkops clkops_omap2_iclk_dflt;
extern const struct clkops clkops_omap2_iclk_idle_only;
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 1fc96b9..119e135 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -20,6 +20,8 @@
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/cpufreq.h>
#include <plat/clock.h>
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 8c96567..d332e7b 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -1,7 +1,7 @@
/*
- * OMAP4 Clock data
+ * OMAP44xx Clock data
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Texas Instruments Incorporated
* Copyright (C) 2009-2010 Nokia Corporation
*
* Paul Walmsley (paul@pwsan.com)
@@ -42,6 +42,10 @@
#define OMAP4430_MODULEMODE_HWCTRL 0
#define OMAP4430_MODULEMODE_SWCTRL 1
+static int omap4_virt_l3_set_rate(struct clk *clk, unsigned long rate);
+static long omap4_virt_l3_round_rate(struct clk *clk, unsigned long rate);
+static unsigned long omap4_virt_l3_recalc(struct clk *clk);
+
/* Root clocks */
static struct clk extalt_clkin_ck = {
@@ -53,7 +57,7 @@ static struct clk extalt_clkin_ck = {
static struct clk pad_clks_ck = {
.name = "pad_clks_ck",
.rate = 12000000,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_CLKSEL_ABE,
.enable_bit = OMAP4430_PAD_CLKS_GATE_SHIFT,
};
@@ -73,7 +77,7 @@ static struct clk secure_32k_clk_src_ck = {
static struct clk slimbus_clk = {
.name = "slimbus_clk",
.rate = 12000000,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_CLKSEL_ABE,
.enable_bit = OMAP4430_SLIMBUS_CLK_GATE_SHIFT,
};
@@ -127,42 +131,42 @@ static struct clk virt_38400000_ck = {
};
static const struct clksel_rate div_1_0_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 0, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_1_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 1, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_2_rates[] = {
- { .div = 1, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 2, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_3_rates[] = {
- { .div = 1, .val = 3, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 3, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_4_rates[] = {
- { .div = 1, .val = 4, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 4, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_5_rates[] = {
- { .div = 1, .val = 5, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 5, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_6_rates[] = {
- { .div = 1, .val = 6, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 6, .flags = RATE_IN_44XX },
{ .div = 0 },
};
static const struct clksel_rate div_1_7_rates[] = {
- { .div = 1, .val = 7, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 7, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -285,37 +289,37 @@ static struct clk dpll_abe_x2_ck = {
};
static const struct clksel_rate div31_1to31_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_4430 },
- { .div = 2, .val = 2, .flags = RATE_IN_4430 },
- { .div = 3, .val = 3, .flags = RATE_IN_4430 },
- { .div = 4, .val = 4, .flags = RATE_IN_4430 },
- { .div = 5, .val = 5, .flags = RATE_IN_4430 },
- { .div = 6, .val = 6, .flags = RATE_IN_4430 },
- { .div = 7, .val = 7, .flags = RATE_IN_4430 },
- { .div = 8, .val = 8, .flags = RATE_IN_4430 },
- { .div = 9, .val = 9, .flags = RATE_IN_4430 },
- { .div = 10, .val = 10, .flags = RATE_IN_4430 },
- { .div = 11, .val = 11, .flags = RATE_IN_4430 },
- { .div = 12, .val = 12, .flags = RATE_IN_4430 },
- { .div = 13, .val = 13, .flags = RATE_IN_4430 },
- { .div = 14, .val = 14, .flags = RATE_IN_4430 },
- { .div = 15, .val = 15, .flags = RATE_IN_4430 },
- { .div = 16, .val = 16, .flags = RATE_IN_4430 },
- { .div = 17, .val = 17, .flags = RATE_IN_4430 },
- { .div = 18, .val = 18, .flags = RATE_IN_4430 },
- { .div = 19, .val = 19, .flags = RATE_IN_4430 },
- { .div = 20, .val = 20, .flags = RATE_IN_4430 },
- { .div = 21, .val = 21, .flags = RATE_IN_4430 },
- { .div = 22, .val = 22, .flags = RATE_IN_4430 },
- { .div = 23, .val = 23, .flags = RATE_IN_4430 },
- { .div = 24, .val = 24, .flags = RATE_IN_4430 },
- { .div = 25, .val = 25, .flags = RATE_IN_4430 },
- { .div = 26, .val = 26, .flags = RATE_IN_4430 },
- { .div = 27, .val = 27, .flags = RATE_IN_4430 },
- { .div = 28, .val = 28, .flags = RATE_IN_4430 },
- { .div = 29, .val = 29, .flags = RATE_IN_4430 },
- { .div = 30, .val = 30, .flags = RATE_IN_4430 },
- { .div = 31, .val = 31, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 1, .flags = RATE_IN_44XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_44XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_44XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_44XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_44XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_44XX },
+ { .div = 7, .val = 7, .flags = RATE_IN_44XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_44XX },
+ { .div = 9, .val = 9, .flags = RATE_IN_44XX },
+ { .div = 10, .val = 10, .flags = RATE_IN_44XX },
+ { .div = 11, .val = 11, .flags = RATE_IN_44XX },
+ { .div = 12, .val = 12, .flags = RATE_IN_44XX },
+ { .div = 13, .val = 13, .flags = RATE_IN_44XX },
+ { .div = 14, .val = 14, .flags = RATE_IN_44XX },
+ { .div = 15, .val = 15, .flags = RATE_IN_44XX },
+ { .div = 16, .val = 16, .flags = RATE_IN_44XX },
+ { .div = 17, .val = 17, .flags = RATE_IN_44XX },
+ { .div = 18, .val = 18, .flags = RATE_IN_44XX },
+ { .div = 19, .val = 19, .flags = RATE_IN_44XX },
+ { .div = 20, .val = 20, .flags = RATE_IN_44XX },
+ { .div = 21, .val = 21, .flags = RATE_IN_44XX },
+ { .div = 22, .val = 22, .flags = RATE_IN_44XX },
+ { .div = 23, .val = 23, .flags = RATE_IN_44XX },
+ { .div = 24, .val = 24, .flags = RATE_IN_44XX },
+ { .div = 25, .val = 25, .flags = RATE_IN_44XX },
+ { .div = 26, .val = 26, .flags = RATE_IN_44XX },
+ { .div = 27, .val = 27, .flags = RATE_IN_44XX },
+ { .div = 28, .val = 28, .flags = RATE_IN_44XX },
+ { .div = 29, .val = 29, .flags = RATE_IN_44XX },
+ { .div = 30, .val = 30, .flags = RATE_IN_44XX },
+ { .div = 31, .val = 31, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -345,9 +349,9 @@ static struct clk abe_24m_fclk = {
};
static const struct clksel_rate div3_1to4_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_4430 },
- { .div = 2, .val = 1, .flags = RATE_IN_4430 },
- { .div = 4, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_44XX },
+ { .div = 4, .val = 2, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -369,8 +373,8 @@ static struct clk abe_clk = {
};
static const struct clksel_rate div2_1to2_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_4430 },
- { .div = 2, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -524,6 +528,15 @@ static struct clk dpll_core_m5x2_ck = {
.set_rate = &omap2_clksel_set_rate,
};
+static struct clk virt_l3_ck = {
+ .name = "virt_l3_ck",
+ .parent = &dpll_core_m5x2_ck,
+ .ops = &clkops_null,
+ .set_rate = &omap4_virt_l3_set_rate,
+ .recalc = &omap4_virt_l3_recalc,
+ .round_rate = &omap4_virt_l3_round_rate,
+};
+
static const struct clksel div_core_div[] = {
{ .parent = &dpll_core_m5x2_ck, .rates = div2_1to2_rates },
{ .parent = NULL },
@@ -542,10 +555,10 @@ static struct clk div_core_ck = {
};
static const struct clksel_rate div4_1to8_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_4430 },
- { .div = 2, .val = 1, .flags = RATE_IN_4430 },
- { .div = 4, .val = 2, .flags = RATE_IN_4430 },
- { .div = 8, .val = 3, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_44XX },
+ { .div = 4, .val = 2, .flags = RATE_IN_44XX },
+ { .div = 8, .val = 3, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -621,7 +634,7 @@ static struct clk dpll_core_m3x2_ck = {
.clksel = dpll_core_m6x2_div,
.clksel_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
.clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
.enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
.recalc = &omap2_clksel_recalc,
@@ -774,6 +787,15 @@ static struct clk dpll_mpu_m2_ck = {
.set_rate = &omap2_clksel_set_rate,
};
+static struct clk virt_dpll_mpu_ck = {
+ .name = "virt_dpll_mpu_ck",
+ .parent = &dpll_mpu_ck,
+ .ops = &clkops_null,
+ .recalc = &omap4460_mpu_dpll_recalc,
+ .round_rate = &omap4460_mpu_dpll_round_rate,
+ .set_rate = &omap4460_mpu_dpll_set_rate,
+};
+
static struct clk per_hs_clk_div_ck = {
.name = "per_hs_clk_div_ck",
.parent = &dpll_abe_m3x2_ck,
@@ -879,7 +901,7 @@ static struct clk dpll_per_m3x2_ck = {
.clksel = dpll_per_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
.clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
.enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
.recalc = &omap2_clksel_recalc,
@@ -1099,8 +1121,8 @@ static struct clk func_24mc_fclk = {
};
static const struct clksel_rate div2_4to8_rates[] = {
- { .div = 4, .val = 0, .flags = RATE_IN_4430 },
- { .div = 8, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 4, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 8, .val = 1, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -1130,8 +1152,8 @@ static struct clk func_48mc_fclk = {
};
static const struct clksel_rate div2_2to4_rates[] = {
- { .div = 2, .val = 0, .flags = RATE_IN_4430 },
- { .div = 4, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 4, .val = 1, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -1183,8 +1205,8 @@ static struct clk hsmmc6_fclk = {
};
static const struct clksel_rate div2_1to8_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_4430 },
- { .div = 8, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 1, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 8, .val = 1, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -1264,6 +1286,13 @@ static struct clk l4_wkup_clk_mux_ck = {
.recalc = &omap2_clksel_recalc,
};
+static struct clk div_ts_ck = {
+ .name = "div_ts_ck",
+ .parent = &l4_wkup_clk_mux_ck,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
static const struct clksel per_abe_nc_fclk_div[] = {
{ .parent = &dpll_abe_m2_ck, .rates = div2_1to2_rates },
{ .parent = NULL },
@@ -1358,7 +1387,7 @@ static struct clk syc_clk_div_ck = {
static struct clk aes1_fck = {
.name = "aes1_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4SEC_AES1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_secure_clkdm",
@@ -1368,7 +1397,7 @@ static struct clk aes1_fck = {
static struct clk aes2_fck = {
.name = "aes2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4SEC_AES2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_secure_clkdm",
@@ -1378,7 +1407,7 @@ static struct clk aes2_fck = {
static struct clk aess_fck = {
.name = "aess_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "abe_clkdm",
@@ -1388,7 +1417,7 @@ static struct clk aess_fck = {
static struct clk bandgap_fclk = {
.name = "bandgap_fclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT,
.clkdm_name = "l4_wkup_clkdm",
@@ -1396,9 +1425,19 @@ static struct clk bandgap_fclk = {
.recalc = &followparent_recalc,
};
+static struct clk bandgap_ts_fclk = {
+ .name = "bandgap_ts_fclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ .enable_bit = OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &div_ts_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk des3des_fck = {
.name = "des3des_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_secure_clkdm",
@@ -1439,7 +1478,7 @@ static struct clk dmic_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -1448,7 +1487,7 @@ static struct clk dmic_fck = {
static struct clk dsp_fck = {
.name = "dsp_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "tesla_clkdm",
@@ -1458,7 +1497,7 @@ static struct clk dsp_fck = {
static struct clk dss_sys_clk = {
.name = "dss_sys_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT,
.clkdm_name = "l3_dss_clkdm",
@@ -1468,7 +1507,7 @@ static struct clk dss_sys_clk = {
static struct clk dss_tv_clk = {
.name = "dss_tv_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_TV_CLK_SHIFT,
.clkdm_name = "l3_dss_clkdm",
@@ -1478,7 +1517,7 @@ static struct clk dss_tv_clk = {
static struct clk dss_dss_clk = {
.name = "dss_dss_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DSSCLK_SHIFT,
.clkdm_name = "l3_dss_clkdm",
@@ -1488,7 +1527,7 @@ static struct clk dss_dss_clk = {
static struct clk dss_48mhz_clk = {
.name = "dss_48mhz_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT,
.clkdm_name = "l3_dss_clkdm",
@@ -1498,7 +1537,7 @@ static struct clk dss_48mhz_clk = {
static struct clk dss_fck = {
.name = "dss_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l3_dss_clkdm",
@@ -1508,7 +1547,7 @@ static struct clk dss_fck = {
static struct clk efuse_ctrl_cust_fck = {
.name = "efuse_ctrl_cust_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_cefuse_clkdm",
@@ -1518,7 +1557,7 @@ static struct clk efuse_ctrl_cust_fck = {
static struct clk emif1_fck = {
.name = "emif1_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.flags = ENABLE_ON_INIT,
@@ -1529,7 +1568,7 @@ static struct clk emif1_fck = {
static struct clk emif2_fck = {
.name = "emif2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.flags = ENABLE_ON_INIT,
@@ -1550,7 +1589,7 @@ static struct clk fdif_fck = {
.clksel = fdif_fclk_div,
.clksel_reg = OMAP4430_CM_CAM_FDIF_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_FCLK_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -1561,7 +1600,7 @@ static struct clk fdif_fck = {
static struct clk fpka_fck = {
.name = "fpka_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_secure_clkdm",
@@ -1571,7 +1610,7 @@ static struct clk fpka_fck = {
static struct clk gpio1_dbclk = {
.name = "gpio1_dbclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
.clkdm_name = "l4_wkup_clkdm",
@@ -1581,7 +1620,7 @@ static struct clk gpio1_dbclk = {
static struct clk gpio1_ick = {
.name = "gpio1_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_wkup_clkdm",
@@ -1591,7 +1630,7 @@ static struct clk gpio1_ick = {
static struct clk gpio2_dbclk = {
.name = "gpio2_dbclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -1601,7 +1640,7 @@ static struct clk gpio2_dbclk = {
static struct clk gpio2_ick = {
.name = "gpio2_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1611,7 +1650,7 @@ static struct clk gpio2_ick = {
static struct clk gpio3_dbclk = {
.name = "gpio3_dbclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -1621,7 +1660,7 @@ static struct clk gpio3_dbclk = {
static struct clk gpio3_ick = {
.name = "gpio3_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1631,7 +1670,7 @@ static struct clk gpio3_ick = {
static struct clk gpio4_dbclk = {
.name = "gpio4_dbclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -1641,7 +1680,7 @@ static struct clk gpio4_dbclk = {
static struct clk gpio4_ick = {
.name = "gpio4_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1651,7 +1690,7 @@ static struct clk gpio4_ick = {
static struct clk gpio5_dbclk = {
.name = "gpio5_dbclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -1661,7 +1700,7 @@ static struct clk gpio5_dbclk = {
static struct clk gpio5_ick = {
.name = "gpio5_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1671,7 +1710,7 @@ static struct clk gpio5_ick = {
static struct clk gpio6_dbclk = {
.name = "gpio6_dbclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -1681,7 +1720,7 @@ static struct clk gpio6_dbclk = {
static struct clk gpio6_ick = {
.name = "gpio6_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1691,7 +1730,7 @@ static struct clk gpio6_ick = {
static struct clk gpmc_ick = {
.name = "gpmc_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3_2_GPMC_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_2_clkdm",
@@ -1713,7 +1752,7 @@ static struct clk gpu_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SGX_FCLK_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -1722,7 +1761,7 @@ static struct clk gpu_fck = {
static struct clk hdq1w_fck = {
.name = "hdq1w_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1742,7 +1781,7 @@ static struct clk hsi_fck = {
.clksel = hsi_fclk_div,
.clksel_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_24_25_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -1753,7 +1792,7 @@ static struct clk hsi_fck = {
static struct clk i2c1_fck = {
.name = "i2c1_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1763,7 +1802,7 @@ static struct clk i2c1_fck = {
static struct clk i2c2_fck = {
.name = "i2c2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1773,7 +1812,7 @@ static struct clk i2c2_fck = {
static struct clk i2c3_fck = {
.name = "i2c3_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1783,7 +1822,7 @@ static struct clk i2c3_fck = {
static struct clk i2c4_fck = {
.name = "i2c4_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -1793,7 +1832,7 @@ static struct clk i2c4_fck = {
static struct clk ipu_fck = {
.name = "ipu_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "ducati_clkdm",
@@ -1803,7 +1842,7 @@ static struct clk ipu_fck = {
static struct clk iss_ctrlclk = {
.name = "iss_ctrlclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,
.clkdm_name = "iss_clkdm",
@@ -1813,7 +1852,7 @@ static struct clk iss_ctrlclk = {
static struct clk iss_fck = {
.name = "iss_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "iss_clkdm",
@@ -1823,7 +1862,7 @@ static struct clk iss_fck = {
static struct clk iva_fck = {
.name = "iva_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "ivahd_clkdm",
@@ -1833,7 +1872,7 @@ static struct clk iva_fck = {
static struct clk kbd_fck = {
.name = "kbd_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_wkup_clkdm",
@@ -1843,7 +1882,7 @@ static struct clk kbd_fck = {
static struct clk l3_instr_ick = {
.name = "l3_instr_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_instr_clkdm",
@@ -1854,7 +1893,7 @@ static struct clk l3_instr_ick = {
static struct clk l3_main_3_ick = {
.name = "l3_main_3_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_instr_clkdm",
@@ -1889,7 +1928,7 @@ static struct clk mcasp_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -1922,7 +1961,7 @@ static struct clk mcbsp1_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -1955,7 +1994,7 @@ static struct clk mcbsp2_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -1988,7 +2027,7 @@ static struct clk mcbsp3_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2020,7 +2059,7 @@ static struct clk mcbsp4_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_SOURCE_24_24_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2029,7 +2068,7 @@ static struct clk mcbsp4_fck = {
static struct clk mcpdm_fck = {
.name = "mcpdm_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "abe_clkdm",
@@ -2039,7 +2078,7 @@ static struct clk mcpdm_fck = {
static struct clk mcspi1_fck = {
.name = "mcspi1_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2049,7 +2088,7 @@ static struct clk mcspi1_fck = {
static struct clk mcspi2_fck = {
.name = "mcspi2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2059,7 +2098,7 @@ static struct clk mcspi2_fck = {
static struct clk mcspi3_fck = {
.name = "mcspi3_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2069,7 +2108,7 @@ static struct clk mcspi3_fck = {
static struct clk mcspi4_fck = {
.name = "mcspi4_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2085,7 +2124,7 @@ static struct clk mmc1_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2100,7 +2139,7 @@ static struct clk mmc2_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2109,7 +2148,7 @@ static struct clk mmc2_fck = {
static struct clk mmc3_fck = {
.name = "mmc3_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2119,7 +2158,7 @@ static struct clk mmc3_fck = {
static struct clk mmc4_fck = {
.name = "mmc4_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2129,7 +2168,7 @@ static struct clk mmc4_fck = {
static struct clk mmc5_fck = {
.name = "mmc5_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2139,7 +2178,7 @@ static struct clk mmc5_fck = {
static struct clk ocp2scp_usb_phy_phy_48m = {
.name = "ocp2scp_usb_phy_phy_48m",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_PHY_48M_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2149,7 +2188,7 @@ static struct clk ocp2scp_usb_phy_phy_48m = {
static struct clk ocp2scp_usb_phy_ick = {
.name = "ocp2scp_usb_phy_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_init_clkdm",
@@ -2159,7 +2198,7 @@ static struct clk ocp2scp_usb_phy_ick = {
static struct clk ocp_wp_noc_ick = {
.name = "ocp_wp_noc_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_instr_clkdm",
@@ -2170,7 +2209,7 @@ static struct clk ocp_wp_noc_ick = {
static struct clk rng_ick = {
.name = "rng_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4SEC_RNG_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_secure_clkdm",
@@ -2180,7 +2219,7 @@ static struct clk rng_ick = {
static struct clk sha2md5_fck = {
.name = "sha2md5_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_secure_clkdm",
@@ -2190,7 +2229,7 @@ static struct clk sha2md5_fck = {
static struct clk sl2if_ick = {
.name = "sl2if_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_IVAHD_SL2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "ivahd_clkdm",
@@ -2200,7 +2239,7 @@ static struct clk sl2if_ick = {
static struct clk slimbus1_fclk_1 = {
.name = "slimbus1_fclk_1",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_FCLK1_SHIFT,
.clkdm_name = "abe_clkdm",
@@ -2210,7 +2249,7 @@ static struct clk slimbus1_fclk_1 = {
static struct clk slimbus1_fclk_0 = {
.name = "slimbus1_fclk_0",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_FCLK0_SHIFT,
.clkdm_name = "abe_clkdm",
@@ -2220,7 +2259,7 @@ static struct clk slimbus1_fclk_0 = {
static struct clk slimbus1_fclk_2 = {
.name = "slimbus1_fclk_2",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_FCLK2_SHIFT,
.clkdm_name = "abe_clkdm",
@@ -2230,7 +2269,7 @@ static struct clk slimbus1_fclk_2 = {
static struct clk slimbus1_slimbus_clk = {
.name = "slimbus1_slimbus_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT,
.clkdm_name = "abe_clkdm",
@@ -2240,7 +2279,7 @@ static struct clk slimbus1_slimbus_clk = {
static struct clk slimbus1_fck = {
.name = "slimbus1_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "abe_clkdm",
@@ -2250,7 +2289,7 @@ static struct clk slimbus1_fck = {
static struct clk slimbus2_fclk_1 = {
.name = "slimbus2_fclk_1",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -2260,7 +2299,7 @@ static struct clk slimbus2_fclk_1 = {
static struct clk slimbus2_fclk_0 = {
.name = "slimbus2_fclk_0",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -2270,7 +2309,7 @@ static struct clk slimbus2_fclk_0 = {
static struct clk slimbus2_slimbus_clk = {
.name = "slimbus2_slimbus_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT,
.clkdm_name = "l4_per_clkdm",
@@ -2280,7 +2319,7 @@ static struct clk slimbus2_slimbus_clk = {
static struct clk slimbus2_fck = {
.name = "slimbus2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2290,7 +2329,7 @@ static struct clk slimbus2_fck = {
static struct clk smartreflex_core_fck = {
.name = "smartreflex_core_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_ao_clkdm",
@@ -2300,7 +2339,7 @@ static struct clk smartreflex_core_fck = {
static struct clk smartreflex_iva_fck = {
.name = "smartreflex_iva_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_ao_clkdm",
@@ -2310,7 +2349,7 @@ static struct clk smartreflex_iva_fck = {
static struct clk smartreflex_mpu_fck = {
.name = "smartreflex_mpu_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_ao_clkdm",
@@ -2326,7 +2365,7 @@ static struct clk timer1_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2341,7 +2380,7 @@ static struct clk timer10_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2356,7 +2395,7 @@ static struct clk timer11_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2371,7 +2410,7 @@ static struct clk timer2_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2386,7 +2425,7 @@ static struct clk timer3_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2401,7 +2440,7 @@ static struct clk timer4_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2422,7 +2461,7 @@ static struct clk timer5_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2437,7 +2476,7 @@ static struct clk timer6_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2452,7 +2491,7 @@ static struct clk timer7_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2467,7 +2506,7 @@ static struct clk timer8_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2482,7 +2521,7 @@ static struct clk timer9_fck = {
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2491,7 +2530,7 @@ static struct clk timer9_fck = {
static struct clk uart1_fck = {
.name = "uart1_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_UART1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2501,7 +2540,7 @@ static struct clk uart1_fck = {
static struct clk uart2_fck = {
.name = "uart2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_UART2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2511,7 +2550,7 @@ static struct clk uart2_fck = {
static struct clk uart3_fck = {
.name = "uart3_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_UART3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2521,7 +2560,7 @@ static struct clk uart3_fck = {
static struct clk uart4_fck = {
.name = "uart4_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L4PER_UART4_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_per_clkdm",
@@ -2531,7 +2570,7 @@ static struct clk uart4_fck = {
static struct clk usb_host_fs_fck = {
.name = "usb_host_fs_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l3_init_clkdm",
@@ -2558,7 +2597,7 @@ static struct clk utmi_p1_gfclk = {
static struct clk usb_host_hs_utmi_p1_clk = {
.name = "usb_host_hs_utmi_p1_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2585,7 +2624,7 @@ static struct clk utmi_p2_gfclk = {
static struct clk usb_host_hs_utmi_p2_clk = {
.name = "usb_host_hs_utmi_p2_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2595,7 +2634,7 @@ static struct clk usb_host_hs_utmi_p2_clk = {
static struct clk usb_host_hs_utmi_p3_clk = {
.name = "usb_host_hs_utmi_p3_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2605,7 +2644,7 @@ static struct clk usb_host_hs_utmi_p3_clk = {
static struct clk usb_host_hs_hsic480m_p1_clk = {
.name = "usb_host_hs_hsic480m_p1_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2615,7 +2654,7 @@ static struct clk usb_host_hs_hsic480m_p1_clk = {
static struct clk usb_host_hs_hsic60m_p1_clk = {
.name = "usb_host_hs_hsic60m_p1_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2625,7 +2664,7 @@ static struct clk usb_host_hs_hsic60m_p1_clk = {
static struct clk usb_host_hs_hsic60m_p2_clk = {
.name = "usb_host_hs_hsic60m_p2_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2635,7 +2674,7 @@ static struct clk usb_host_hs_hsic60m_p2_clk = {
static struct clk usb_host_hs_hsic480m_p2_clk = {
.name = "usb_host_hs_hsic480m_p2_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2645,7 +2684,7 @@ static struct clk usb_host_hs_hsic480m_p2_clk = {
static struct clk usb_host_hs_func48mclk = {
.name = "usb_host_hs_func48mclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2655,7 +2694,7 @@ static struct clk usb_host_hs_func48mclk = {
static struct clk usb_host_hs_fck = {
.name = "usb_host_hs_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l3_init_clkdm",
@@ -2682,7 +2721,7 @@ static struct clk otg_60m_gfclk = {
static struct clk usb_otg_hs_xclk = {
.name = "usb_otg_hs_xclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_XCLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2692,7 +2731,7 @@ static struct clk usb_otg_hs_xclk = {
static struct clk usb_otg_hs_ick = {
.name = "usb_otg_hs_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_init_clkdm",
@@ -2702,7 +2741,7 @@ static struct clk usb_otg_hs_ick = {
static struct clk usb_phy_cm_clk32k = {
.name = "usb_phy_cm_clk32k",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_ALWON_USBPHY_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_CLK32K_SHIFT,
.clkdm_name = "l4_ao_clkdm",
@@ -2712,7 +2751,7 @@ static struct clk usb_phy_cm_clk32k = {
static struct clk usb_tll_hs_usb_ch2_clk = {
.name = "usb_tll_hs_usb_ch2_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2722,7 +2761,7 @@ static struct clk usb_tll_hs_usb_ch2_clk = {
static struct clk usb_tll_hs_usb_ch0_clk = {
.name = "usb_tll_hs_usb_ch0_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2732,7 +2771,7 @@ static struct clk usb_tll_hs_usb_ch0_clk = {
static struct clk usb_tll_hs_usb_ch1_clk = {
.name = "usb_tll_hs_usb_ch1_clk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
@@ -2742,7 +2781,7 @@ static struct clk usb_tll_hs_usb_ch1_clk = {
static struct clk usb_tll_hs_ick = {
.name = "usb_tll_hs_ick",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_init_clkdm",
@@ -2751,8 +2790,8 @@ static struct clk usb_tll_hs_ick = {
};
static const struct clksel_rate div2_14to18_rates[] = {
- { .div = 14, .val = 0, .flags = RATE_IN_4430 },
- { .div = 18, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 14, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 18, .val = 1, .flags = RATE_IN_44XX },
{ .div = 0 },
};
@@ -2775,7 +2814,7 @@ static struct clk usim_ck = {
static struct clk usim_fclk = {
.name = "usim_fclk",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_FCLK_SHIFT,
.clkdm_name = "l4_wkup_clkdm",
@@ -2785,7 +2824,7 @@ static struct clk usim_fclk = {
static struct clk usim_fck = {
.name = "usim_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l4_wkup_clkdm",
@@ -2795,7 +2834,7 @@ static struct clk usim_fck = {
static struct clk wd_timer2_fck = {
.name = "wd_timer2_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l4_wkup_clkdm",
@@ -2805,7 +2844,7 @@ static struct clk wd_timer2_fck = {
static struct clk wd_timer3_fck = {
.name = "wd_timer3_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "abe_clkdm",
@@ -2850,19 +2889,39 @@ static struct clk trace_clk_div_ck = {
/* SCRM aux clk nodes */
-static const struct clksel auxclk_sel[] = {
+static const struct clksel auxclk_src_sel[] = {
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
{ .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates },
{ .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates },
{ .parent = NULL },
};
-static struct clk auxclk0_ck = {
- .name = "auxclk0_ck",
+static const struct clksel_rate div16_1to16_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_44XX },
+ { .div = 3, .val = 2, .flags = RATE_IN_44XX },
+ { .div = 4, .val = 3, .flags = RATE_IN_44XX },
+ { .div = 5, .val = 4, .flags = RATE_IN_44XX },
+ { .div = 6, .val = 5, .flags = RATE_IN_44XX },
+ { .div = 7, .val = 6, .flags = RATE_IN_44XX },
+ { .div = 8, .val = 7, .flags = RATE_IN_44XX },
+ { .div = 9, .val = 8, .flags = RATE_IN_44XX },
+ { .div = 10, .val = 9, .flags = RATE_IN_44XX },
+ { .div = 11, .val = 10, .flags = RATE_IN_44XX },
+ { .div = 12, .val = 11, .flags = RATE_IN_44XX },
+ { .div = 13, .val = 12, .flags = RATE_IN_44XX },
+ { .div = 14, .val = 13, .flags = RATE_IN_44XX },
+ { .div = 15, .val = 14, .flags = RATE_IN_44XX },
+ { .div = 16, .val = 15, .flags = RATE_IN_44XX },
+ { .div = 0 },
+};
+
+static struct clk auxclk0_src_ck = {
+ .name = "auxclk0_src_ck",
.parent = &sys_clkin_ck,
.init = &omap2_init_clksel_parent,
- .ops = &clkops_omap2_dflt,
- .clksel = auxclk_sel,
+ .ops = &clkops_omap4_dflt_wait,
+ .clksel = auxclk_src_sel,
.clksel_reg = OMAP4_SCRM_AUXCLK0,
.clksel_mask = OMAP4_SRCSELECT_MASK,
.recalc = &omap2_clksel_recalc,
@@ -2870,12 +2929,29 @@ static struct clk auxclk0_ck = {
.enable_bit = OMAP4_ENABLE_SHIFT,
};
-static struct clk auxclk1_ck = {
- .name = "auxclk1_ck",
+static const struct clksel auxclk0_sel[] = {
+ { .parent = &auxclk0_src_ck, .rates = div16_1to16_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk0_ck = {
+ .name = "auxclk0_ck",
+ .parent = &auxclk0_src_ck,
+ .clksel = auxclk0_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK0,
+ .clksel_mask = OMAP4_CLKDIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk auxclk1_src_ck = {
+ .name = "auxclk1_src_ck",
.parent = &sys_clkin_ck,
.init = &omap2_init_clksel_parent,
- .ops = &clkops_omap2_dflt,
- .clksel = auxclk_sel,
+ .ops = &clkops_omap4_dflt_wait,
+ .clksel = auxclk_src_sel,
.clksel_reg = OMAP4_SCRM_AUXCLK1,
.clksel_mask = OMAP4_SRCSELECT_MASK,
.recalc = &omap2_clksel_recalc,
@@ -2883,24 +2959,59 @@ static struct clk auxclk1_ck = {
.enable_bit = OMAP4_ENABLE_SHIFT,
};
-static struct clk auxclk2_ck = {
- .name = "auxclk2_ck",
+static const struct clksel auxclk1_sel[] = {
+ { .parent = &auxclk1_src_ck, .rates = div16_1to16_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk1_ck = {
+ .name = "auxclk1_ck",
+ .parent = &auxclk1_src_ck,
+ .clksel = auxclk1_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK1,
+ .clksel_mask = OMAP4_CLKDIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk auxclk2_src_ck = {
+ .name = "auxclk2_src_ck",
.parent = &sys_clkin_ck,
.init = &omap2_init_clksel_parent,
- .ops = &clkops_omap2_dflt,
- .clksel = auxclk_sel,
+ .ops = &clkops_omap4_dflt_wait,
+ .clksel = auxclk_src_sel,
.clksel_reg = OMAP4_SCRM_AUXCLK2,
.clksel_mask = OMAP4_SRCSELECT_MASK,
.recalc = &omap2_clksel_recalc,
.enable_reg = OMAP4_SCRM_AUXCLK2,
.enable_bit = OMAP4_ENABLE_SHIFT,
};
-static struct clk auxclk3_ck = {
- .name = "auxclk3_ck",
+
+static const struct clksel auxclk2_sel[] = {
+ { .parent = &auxclk2_src_ck, .rates = div16_1to16_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk2_ck = {
+ .name = "auxclk2_ck",
+ .parent = &auxclk2_src_ck,
+ .clksel = auxclk2_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK2,
+ .clksel_mask = OMAP4_CLKDIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk auxclk3_src_ck = {
+ .name = "auxclk3_src_ck",
.parent = &sys_clkin_ck,
.init = &omap2_init_clksel_parent,
- .ops = &clkops_omap2_dflt,
- .clksel = auxclk_sel,
+ .ops = &clkops_omap4_dflt_wait,
+ .clksel = auxclk_src_sel,
.clksel_reg = OMAP4_SCRM_AUXCLK3,
.clksel_mask = OMAP4_SRCSELECT_MASK,
.recalc = &omap2_clksel_recalc,
@@ -2908,12 +3019,29 @@ static struct clk auxclk3_ck = {
.enable_bit = OMAP4_ENABLE_SHIFT,
};
-static struct clk auxclk4_ck = {
- .name = "auxclk4_ck",
+static const struct clksel auxclk3_sel[] = {
+ { .parent = &auxclk3_src_ck, .rates = div16_1to16_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk3_ck = {
+ .name = "auxclk3_ck",
+ .parent = &auxclk3_src_ck,
+ .clksel = auxclk3_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK3,
+ .clksel_mask = OMAP4_CLKDIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk auxclk4_src_ck = {
+ .name = "auxclk4_src_ck",
.parent = &sys_clkin_ck,
.init = &omap2_init_clksel_parent,
- .ops = &clkops_omap2_dflt,
- .clksel = auxclk_sel,
+ .ops = &clkops_omap4_dflt_wait,
+ .clksel = auxclk_src_sel,
.clksel_reg = OMAP4_SCRM_AUXCLK4,
.clksel_mask = OMAP4_SRCSELECT_MASK,
.recalc = &omap2_clksel_recalc,
@@ -2921,12 +3049,29 @@ static struct clk auxclk4_ck = {
.enable_bit = OMAP4_ENABLE_SHIFT,
};
-static struct clk auxclk5_ck = {
- .name = "auxclk5_ck",
+static const struct clksel auxclk4_sel[] = {
+ { .parent = &auxclk4_src_ck, .rates = div16_1to16_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk4_ck = {
+ .name = "auxclk4_ck",
+ .parent = &auxclk4_src_ck,
+ .clksel = auxclk4_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK4,
+ .clksel_mask = OMAP4_CLKDIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk auxclk5_src_ck = {
+ .name = "auxclk5_src_ck",
.parent = &sys_clkin_ck,
.init = &omap2_init_clksel_parent,
- .ops = &clkops_omap2_dflt,
- .clksel = auxclk_sel,
+ .ops = &clkops_omap4_dflt_wait,
+ .clksel = auxclk_src_sel,
.clksel_reg = OMAP4_SCRM_AUXCLK5,
.clksel_mask = OMAP4_SRCSELECT_MASK,
.recalc = &omap2_clksel_recalc,
@@ -2934,6 +3079,23 @@ static struct clk auxclk5_ck = {
.enable_bit = OMAP4_ENABLE_SHIFT,
};
+static const struct clksel auxclk5_sel[] = {
+ { .parent = &auxclk5_src_ck, .rates = div16_1to16_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk5_ck = {
+ .name = "auxclk5_ck",
+ .parent = &auxclk5_src_ck,
+ .clksel = auxclk5_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK5,
+ .clksel_mask = OMAP4_CLKDIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
static const struct clksel auxclkreq_sel[] = {
{ .parent = &auxclk0_ck, .rates = div_1_0_rates },
{ .parent = &auxclk1_ck, .rates = div_1_1_rates },
@@ -3010,289 +3172,411 @@ static struct clk auxclkreq5_ck = {
.recalc = &omap2_clksel_recalc,
};
+static struct clk smp_twd = {
+ .name = "smp_twd",
+ .parent = &dpll_mpu_ck,
+ .ops = &clkops_null,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
/*
* clkdev
*/
static struct omap_clk omap44xx_clks[] = {
- CLK(NULL, "extalt_clkin_ck", &extalt_clkin_ck, CK_443X),
- CLK(NULL, "pad_clks_ck", &pad_clks_ck, CK_443X),
- CLK(NULL, "pad_slimbus_core_clks_ck", &pad_slimbus_core_clks_ck, CK_443X),
- CLK(NULL, "secure_32k_clk_src_ck", &secure_32k_clk_src_ck, CK_443X),
- CLK(NULL, "slimbus_clk", &slimbus_clk, CK_443X),
- CLK(NULL, "sys_32k_ck", &sys_32k_ck, CK_443X),
- CLK(NULL, "virt_12000000_ck", &virt_12000000_ck, CK_443X),
- CLK(NULL, "virt_13000000_ck", &virt_13000000_ck, CK_443X),
- CLK(NULL, "virt_16800000_ck", &virt_16800000_ck, CK_443X),
- CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_443X),
- CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_443X),
- CLK(NULL, "virt_27000000_ck", &virt_27000000_ck, CK_443X),
- CLK(NULL, "virt_38400000_ck", &virt_38400000_ck, CK_443X),
- CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_443X),
- CLK(NULL, "tie_low_clock_ck", &tie_low_clock_ck, CK_443X),
- CLK(NULL, "utmi_phy_clkout_ck", &utmi_phy_clkout_ck, CK_443X),
- CLK(NULL, "xclk60mhsp1_ck", &xclk60mhsp1_ck, CK_443X),
- CLK(NULL, "xclk60mhsp2_ck", &xclk60mhsp2_ck, CK_443X),
- CLK(NULL, "xclk60motg_ck", &xclk60motg_ck, CK_443X),
- CLK(NULL, "abe_dpll_bypass_clk_mux_ck", &abe_dpll_bypass_clk_mux_ck, CK_443X),
- CLK(NULL, "abe_dpll_refclk_mux_ck", &abe_dpll_refclk_mux_ck, CK_443X),
- CLK(NULL, "dpll_abe_ck", &dpll_abe_ck, CK_443X),
- CLK(NULL, "dpll_abe_x2_ck", &dpll_abe_x2_ck, CK_443X),
- CLK(NULL, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, CK_443X),
- CLK(NULL, "abe_24m_fclk", &abe_24m_fclk, CK_443X),
- CLK(NULL, "abe_clk", &abe_clk, CK_443X),
- CLK(NULL, "aess_fclk", &aess_fclk, CK_443X),
- CLK(NULL, "dpll_abe_m3x2_ck", &dpll_abe_m3x2_ck, CK_443X),
- CLK(NULL, "core_hsd_byp_clk_mux_ck", &core_hsd_byp_clk_mux_ck, CK_443X),
- CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_443X),
- CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_443X),
- CLK(NULL, "dpll_core_m6x2_ck", &dpll_core_m6x2_ck, CK_443X),
- CLK(NULL, "dbgclk_mux_ck", &dbgclk_mux_ck, CK_443X),
- CLK(NULL, "dpll_core_m2_ck", &dpll_core_m2_ck, CK_443X),
- CLK(NULL, "ddrphy_ck", &ddrphy_ck, CK_443X),
- CLK(NULL, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck, CK_443X),
- CLK(NULL, "div_core_ck", &div_core_ck, CK_443X),
- CLK(NULL, "div_iva_hs_clk", &div_iva_hs_clk, CK_443X),
- CLK(NULL, "div_mpu_hs_clk", &div_mpu_hs_clk, CK_443X),
- CLK(NULL, "dpll_core_m4x2_ck", &dpll_core_m4x2_ck, CK_443X),
- CLK(NULL, "dll_clk_div_ck", &dll_clk_div_ck, CK_443X),
- CLK(NULL, "dpll_abe_m2_ck", &dpll_abe_m2_ck, CK_443X),
- CLK(NULL, "dpll_core_m3x2_ck", &dpll_core_m3x2_ck, CK_443X),
- CLK(NULL, "dpll_core_m7x2_ck", &dpll_core_m7x2_ck, CK_443X),
- CLK(NULL, "iva_hsd_byp_clk_mux_ck", &iva_hsd_byp_clk_mux_ck, CK_443X),
- CLK(NULL, "dpll_iva_ck", &dpll_iva_ck, CK_443X),
- CLK(NULL, "dpll_iva_x2_ck", &dpll_iva_x2_ck, CK_443X),
- CLK(NULL, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, CK_443X),
- CLK(NULL, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, CK_443X),
- CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_443X),
- CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_443X),
- CLK(NULL, "per_hs_clk_div_ck", &per_hs_clk_div_ck, CK_443X),
- CLK(NULL, "per_hsd_byp_clk_mux_ck", &per_hsd_byp_clk_mux_ck, CK_443X),
- CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_443X),
- CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_443X),
- CLK(NULL, "dpll_per_x2_ck", &dpll_per_x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m3x2_ck", &dpll_per_m3x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m6x2_ck", &dpll_per_m6x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m7x2_ck", &dpll_per_m7x2_ck, CK_443X),
- CLK(NULL, "dpll_unipro_ck", &dpll_unipro_ck, CK_443X),
- CLK(NULL, "dpll_unipro_x2_ck", &dpll_unipro_x2_ck, CK_443X),
- CLK(NULL, "dpll_unipro_m2x2_ck", &dpll_unipro_m2x2_ck, CK_443X),
- CLK(NULL, "usb_hs_clk_div_ck", &usb_hs_clk_div_ck, CK_443X),
- CLK(NULL, "dpll_usb_ck", &dpll_usb_ck, CK_443X),
- CLK(NULL, "dpll_usb_clkdcoldo_ck", &dpll_usb_clkdcoldo_ck, CK_443X),
- CLK(NULL, "dpll_usb_m2_ck", &dpll_usb_m2_ck, CK_443X),
- CLK(NULL, "ducati_clk_mux_ck", &ducati_clk_mux_ck, CK_443X),
- CLK(NULL, "func_12m_fclk", &func_12m_fclk, CK_443X),
- CLK(NULL, "func_24m_clk", &func_24m_clk, CK_443X),
- CLK(NULL, "func_24mc_fclk", &func_24mc_fclk, CK_443X),
- CLK(NULL, "func_48m_fclk", &func_48m_fclk, CK_443X),
- CLK(NULL, "func_48mc_fclk", &func_48mc_fclk, CK_443X),
- CLK(NULL, "func_64m_fclk", &func_64m_fclk, CK_443X),
- CLK(NULL, "func_96m_fclk", &func_96m_fclk, CK_443X),
- CLK(NULL, "hsmmc6_fclk", &hsmmc6_fclk, CK_443X),
- CLK(NULL, "init_60m_fclk", &init_60m_fclk, CK_443X),
- CLK(NULL, "l3_div_ck", &l3_div_ck, CK_443X),
- CLK(NULL, "l4_div_ck", &l4_div_ck, CK_443X),
- CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_443X),
- CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_443X),
- CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_443X),
- CLK(NULL, "mcasp2_fclk", &mcasp2_fclk, CK_443X),
- CLK(NULL, "mcasp3_fclk", &mcasp3_fclk, CK_443X),
- CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_443X),
- CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_443X),
- CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_443X),
- CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_443X),
- CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_443X),
- CLK(NULL, "aes1_fck", &aes1_fck, CK_443X),
- CLK(NULL, "aes2_fck", &aes2_fck, CK_443X),
- CLK(NULL, "aess_fck", &aess_fck, CK_443X),
+ CLK(NULL, "extalt_clkin_ck", &extalt_clkin_ck, CK_44XX),
+ CLK(NULL, "pad_clks_ck", &pad_clks_ck, CK_44XX),
+ CLK(NULL, "pad_slimbus_core_clks_ck", &pad_slimbus_core_clks_ck, CK_44XX),
+ CLK(NULL, "secure_32k_clk_src_ck", &secure_32k_clk_src_ck, CK_44XX),
+ CLK(NULL, "slimbus_clk", &slimbus_clk, CK_44XX),
+ CLK(NULL, "sys_32k_ck", &sys_32k_ck, CK_44XX),
+ CLK(NULL, "virt_12000000_ck", &virt_12000000_ck, CK_44XX),
+ CLK(NULL, "virt_13000000_ck", &virt_13000000_ck, CK_44XX),
+ CLK(NULL, "virt_16800000_ck", &virt_16800000_ck, CK_44XX),
+ CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_44XX),
+ CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_44XX),
+ CLK(NULL, "virt_27000000_ck", &virt_27000000_ck, CK_44XX),
+ CLK(NULL, "virt_38400000_ck", &virt_38400000_ck, CK_44XX),
+ CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_44XX),
+ CLK(NULL, "tie_low_clock_ck", &tie_low_clock_ck, CK_44XX),
+ CLK(NULL, "utmi_phy_clkout_ck", &utmi_phy_clkout_ck, CK_44XX),
+ CLK(NULL, "xclk60mhsp1_ck", &xclk60mhsp1_ck, CK_44XX),
+ CLK(NULL, "xclk60mhsp2_ck", &xclk60mhsp2_ck, CK_44XX),
+ CLK(NULL, "xclk60motg_ck", &xclk60motg_ck, CK_44XX),
+ CLK(NULL, "abe_dpll_bypass_clk_mux_ck", &abe_dpll_bypass_clk_mux_ck, CK_44XX),
+ CLK(NULL, "abe_dpll_refclk_mux_ck", &abe_dpll_refclk_mux_ck, CK_44XX),
+ CLK(NULL, "dpll_abe_ck", &dpll_abe_ck, CK_44XX),
+ CLK(NULL, "dpll_abe_x2_ck", &dpll_abe_x2_ck, CK_44XX),
+ CLK(NULL, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, CK_44XX),
+ CLK(NULL, "abe_24m_fclk", &abe_24m_fclk, CK_44XX),
+ CLK(NULL, "abe_clk", &abe_clk, CK_44XX),
+ CLK(NULL, "aess_fclk", &aess_fclk, CK_44XX),
+ CLK(NULL, "dpll_abe_m3x2_ck", &dpll_abe_m3x2_ck, CK_44XX),
+ CLK(NULL, "core_hsd_byp_clk_mux_ck", &core_hsd_byp_clk_mux_ck, CK_44XX),
+ CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_44XX),
+ CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_44XX),
+ CLK(NULL, "dpll_core_m6x2_ck", &dpll_core_m6x2_ck, CK_44XX),
+ CLK(NULL, "dbgclk_mux_ck", &dbgclk_mux_ck, CK_44XX),
+ CLK(NULL, "dpll_core_m2_ck", &dpll_core_m2_ck, CK_44XX),
+ CLK(NULL, "ddrphy_ck", &ddrphy_ck, CK_44XX),
+ CLK(NULL, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck, CK_44XX),
+ CLK(NULL, "virt_l3_ck", &virt_l3_ck, CK_44XX),
+ CLK(NULL, "div_core_ck", &div_core_ck, CK_44XX),
+ CLK(NULL, "div_iva_hs_clk", &div_iva_hs_clk, CK_44XX),
+ CLK(NULL, "div_mpu_hs_clk", &div_mpu_hs_clk, CK_44XX),
+ CLK(NULL, "dpll_core_m4x2_ck", &dpll_core_m4x2_ck, CK_44XX),
+ CLK(NULL, "dll_clk_div_ck", &dll_clk_div_ck, CK_44XX),
+ CLK(NULL, "dpll_abe_m2_ck", &dpll_abe_m2_ck, CK_44XX),
+ CLK(NULL, "dpll_core_m3x2_ck", &dpll_core_m3x2_ck, CK_44XX),
+ CLK(NULL, "dpll_core_m7x2_ck", &dpll_core_m7x2_ck, CK_44XX),
+ CLK(NULL, "iva_hsd_byp_clk_mux_ck", &iva_hsd_byp_clk_mux_ck, CK_44XX),
+ CLK(NULL, "dpll_iva_ck", &dpll_iva_ck, CK_44XX),
+ CLK(NULL, "dpll_iva_x2_ck", &dpll_iva_x2_ck, CK_44XX),
+ CLK(NULL, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, CK_44XX),
+ CLK(NULL, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, CK_44XX),
+ CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_44XX),
+ CLK(NULL, "virt_dpll_mpu_ck", &virt_dpll_mpu_ck, CK_446X),
+ CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_44XX),
+ CLK(NULL, "per_hs_clk_div_ck", &per_hs_clk_div_ck, CK_44XX),
+ CLK(NULL, "per_hsd_byp_clk_mux_ck", &per_hsd_byp_clk_mux_ck, CK_44XX),
+ CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_x2_ck", &dpll_per_x2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m3x2_ck", &dpll_per_m3x2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m6x2_ck", &dpll_per_m6x2_ck, CK_44XX),
+ CLK(NULL, "dpll_per_m7x2_ck", &dpll_per_m7x2_ck, CK_44XX),
+ CLK(NULL, "dpll_unipro_ck", &dpll_unipro_ck, CK_44XX),
+ CLK(NULL, "dpll_unipro_x2_ck", &dpll_unipro_x2_ck, CK_44XX),
+ CLK(NULL, "dpll_unipro_m2x2_ck", &dpll_unipro_m2x2_ck, CK_44XX),
+ CLK(NULL, "usb_hs_clk_div_ck", &usb_hs_clk_div_ck, CK_44XX),
+ CLK(NULL, "dpll_usb_ck", &dpll_usb_ck, CK_44XX),
+ CLK(NULL, "dpll_usb_clkdcoldo_ck", &dpll_usb_clkdcoldo_ck, CK_44XX),
+ CLK(NULL, "dpll_usb_m2_ck", &dpll_usb_m2_ck, CK_44XX),
+ CLK(NULL, "ducati_clk_mux_ck", &ducati_clk_mux_ck, CK_44XX),
+ CLK(NULL, "func_12m_fclk", &func_12m_fclk, CK_44XX),
+ CLK(NULL, "func_24m_clk", &func_24m_clk, CK_44XX),
+ CLK(NULL, "func_24mc_fclk", &func_24mc_fclk, CK_44XX),
+ CLK(NULL, "func_48m_fclk", &func_48m_fclk, CK_44XX),
+ CLK(NULL, "func_48mc_fclk", &func_48mc_fclk, CK_44XX),
+ CLK(NULL, "func_64m_fclk", &func_64m_fclk, CK_44XX),
+ CLK(NULL, "func_96m_fclk", &func_96m_fclk, CK_44XX),
+ CLK(NULL, "hsmmc6_fclk", &hsmmc6_fclk, CK_44XX),
+ CLK(NULL, "init_60m_fclk", &init_60m_fclk, CK_44XX),
+ CLK(NULL, "l3_div_ck", &l3_div_ck, CK_44XX),
+ CLK(NULL, "l4_div_ck", &l4_div_ck, CK_44XX),
+ CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_44XX),
+ CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_44XX),
+ CLK(NULL, "div_ts_ck", &div_ts_ck, CK_446X),
+ CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_44XX),
+ CLK(NULL, "mcasp2_fclk", &mcasp2_fclk, CK_44XX),
+ CLK(NULL, "mcasp3_fclk", &mcasp3_fclk, CK_44XX),
+ CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_44XX),
+ CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_44XX),
+ CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_44XX),
+ CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_44XX),
+ CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_44XX),
+ CLK(NULL, "aes1_fck", &aes1_fck, CK_44XX),
+ CLK(NULL, "aes2_fck", &aes2_fck, CK_44XX),
+ CLK(NULL, "aess_fck", &aess_fck, CK_44XX),
CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X),
- CLK(NULL, "des3des_fck", &des3des_fck, CK_443X),
- CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
- CLK(NULL, "dmic_fck", &dmic_fck, CK_443X),
- CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
- CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X),
- CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X),
- CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X),
- CLK("omapdss_dss", "fck", &dss_dss_clk, CK_443X),
- CLK("omapdss_dss", "ick", &dss_fck, CK_443X),
- CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
- CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
- CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
- CLK(NULL, "fdif_fck", &fdif_fck, CK_443X),
- CLK(NULL, "fpka_fck", &fpka_fck, CK_443X),
- CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X),
- CLK(NULL, "gpio1_ick", &gpio1_ick, CK_443X),
- CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X),
- CLK(NULL, "gpio2_ick", &gpio2_ick, CK_443X),
- CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X),
- CLK(NULL, "gpio3_ick", &gpio3_ick, CK_443X),
- CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X),
- CLK(NULL, "gpio4_ick", &gpio4_ick, CK_443X),
- CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X),
- CLK(NULL, "gpio5_ick", &gpio5_ick, CK_443X),
- CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X),
- CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X),
- CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X),
- CLK(NULL, "gpu_fck", &gpu_fck, CK_443X),
- CLK("omap2_hdq.0", "fck", &hdq1w_fck, CK_443X),
- CLK(NULL, "hsi_fck", &hsi_fck, CK_443X),
- CLK("omap_i2c.1", "fck", &i2c1_fck, CK_443X),
- CLK("omap_i2c.2", "fck", &i2c2_fck, CK_443X),
- CLK("omap_i2c.3", "fck", &i2c3_fck, CK_443X),
- CLK("omap_i2c.4", "fck", &i2c4_fck, CK_443X),
- CLK(NULL, "ipu_fck", &ipu_fck, CK_443X),
- CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X),
- CLK(NULL, "iss_fck", &iss_fck, CK_443X),
- CLK(NULL, "iva_fck", &iva_fck, CK_443X),
- CLK(NULL, "kbd_fck", &kbd_fck, CK_443X),
- CLK(NULL, "l3_instr_ick", &l3_instr_ick, CK_443X),
- CLK(NULL, "l3_main_3_ick", &l3_main_3_ick, CK_443X),
- CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X),
- CLK(NULL, "mcasp_fck", &mcasp_fck, CK_443X),
- CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X),
- CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_443X),
- CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X),
- CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_443X),
- CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X),
- CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_443X),
- CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X),
- CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_443X),
- CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_443X),
- CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_443X),
- CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_443X),
- CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_443X),
- CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_443X),
- CLK("omap_hsmmc.0", "fck", &mmc1_fck, CK_443X),
- CLK("omap_hsmmc.1", "fck", &mmc2_fck, CK_443X),
- CLK("omap_hsmmc.2", "fck", &mmc3_fck, CK_443X),
- CLK("omap_hsmmc.3", "fck", &mmc4_fck, CK_443X),
- CLK("omap_hsmmc.4", "fck", &mmc5_fck, CK_443X),
- CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
- CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X),
- CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X),
- CLK("omap_rng", "ick", &rng_ick, CK_443X),
- CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
- CLK(NULL, "sl2if_ick", &sl2if_ick, CK_443X),
- CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X),
- CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X),
- CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X),
- CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X),
- CLK(NULL, "slimbus1_fck", &slimbus1_fck, CK_443X),
- CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X),
- CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X),
- CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X),
- CLK(NULL, "slimbus2_fck", &slimbus2_fck, CK_443X),
- CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X),
- CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X),
- CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X),
- CLK(NULL, "gpt1_fck", &timer1_fck, CK_443X),
- CLK(NULL, "gpt10_fck", &timer10_fck, CK_443X),
- CLK(NULL, "gpt11_fck", &timer11_fck, CK_443X),
- CLK(NULL, "gpt2_fck", &timer2_fck, CK_443X),
- CLK(NULL, "gpt3_fck", &timer3_fck, CK_443X),
- CLK(NULL, "gpt4_fck", &timer4_fck, CK_443X),
- CLK(NULL, "gpt5_fck", &timer5_fck, CK_443X),
- CLK(NULL, "gpt6_fck", &timer6_fck, CK_443X),
- CLK(NULL, "gpt7_fck", &timer7_fck, CK_443X),
- CLK(NULL, "gpt8_fck", &timer8_fck, CK_443X),
- CLK(NULL, "gpt9_fck", &timer9_fck, CK_443X),
- CLK(NULL, "uart1_fck", &uart1_fck, CK_443X),
- CLK(NULL, "uart2_fck", &uart2_fck, CK_443X),
- CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
- CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
- CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
- CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X),
- CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
- CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
- CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
- CLK(NULL, "usb_host_hs_utmi_p2_clk", &usb_host_hs_utmi_p2_clk, CK_443X),
- CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X),
- CLK(NULL, "usb_host_hs_hsic480m_p1_clk", &usb_host_hs_hsic480m_p1_clk, CK_443X),
- CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X),
- CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
- CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
- CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
- CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X),
- CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X),
- CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X),
- CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
- CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
- CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X),
- CLK(NULL, "usb_phy_cm_clk32k", &usb_phy_cm_clk32k, CK_443X),
- CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X),
- CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
- CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
- CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X),
- CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
- CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X),
- CLK(NULL, "usim_ck", &usim_ck, CK_443X),
- CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
- CLK(NULL, "usim_fck", &usim_fck, CK_443X),
- CLK("omap_wdt", "fck", &wd_timer2_fck, CK_443X),
- CLK(NULL, "mailboxes_ick", &dummy_ck, CK_443X),
- CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X),
- CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X),
- CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck, CK_443X),
- CLK(NULL, "gpmc_ck", &dummy_ck, CK_443X),
- CLK(NULL, "gpt1_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt2_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt3_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt4_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt5_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt6_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt7_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt8_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt9_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt10_ick", &dummy_ck, CK_443X),
- CLK(NULL, "gpt11_ick", &dummy_ck, CK_443X),
- CLK("omap_i2c.1", "ick", &dummy_ck, CK_443X),
- CLK("omap_i2c.2", "ick", &dummy_ck, CK_443X),
- CLK("omap_i2c.3", "ick", &dummy_ck, CK_443X),
- CLK("omap_i2c.4", "ick", &dummy_ck, CK_443X),
- CLK("omap_hsmmc.0", "ick", &dummy_ck, CK_443X),
- CLK("omap_hsmmc.1", "ick", &dummy_ck, CK_443X),
- CLK("omap_hsmmc.2", "ick", &dummy_ck, CK_443X),
- CLK("omap_hsmmc.3", "ick", &dummy_ck, CK_443X),
- CLK("omap_hsmmc.4", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X),
- CLK(NULL, "uart1_ick", &dummy_ck, CK_443X),
- CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
- CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
- CLK(NULL, "uart4_ick", &dummy_ck, CK_443X),
- CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
- CLK(NULL, "auxclk0_ck", &auxclk0_ck, CK_443X),
- CLK(NULL, "auxclk1_ck", &auxclk1_ck, CK_443X),
- CLK(NULL, "auxclk2_ck", &auxclk2_ck, CK_443X),
- CLK(NULL, "auxclk3_ck", &auxclk3_ck, CK_443X),
- CLK(NULL, "auxclk4_ck", &auxclk4_ck, CK_443X),
- CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X),
- CLK(NULL, "auxclkreq0_ck", &auxclkreq0_ck, CK_443X),
- CLK(NULL, "auxclkreq1_ck", &auxclkreq1_ck, CK_443X),
- CLK(NULL, "auxclkreq2_ck", &auxclkreq2_ck, CK_443X),
- CLK(NULL, "auxclkreq3_ck", &auxclkreq3_ck, CK_443X),
- CLK(NULL, "auxclkreq4_ck", &auxclkreq4_ck, CK_443X),
- CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_443X),
-};
+ CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X),
+ CLK(NULL, "des3des_fck", &des3des_fck, CK_44XX),
+ CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_44XX),
+ CLK(NULL, "dmic_fck", &dmic_fck, CK_44XX),
+ CLK(NULL, "dsp_fck", &dsp_fck, CK_44XX),
+ CLK(NULL, "sys_clk", &dss_sys_clk, CK_44XX),
+ CLK(NULL, "tv_clk", &dss_tv_clk, CK_44XX),
+ CLK(NULL, "video_clk", &dss_48mhz_clk, CK_44XX),
+ CLK(NULL, "fck", &dss_dss_clk, CK_44XX),
+ CLK(NULL, "ick", &dss_fck, CK_44XX),
+ CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_44XX),
+ CLK(NULL, "emif1_fck", &emif1_fck, CK_44XX),
+ CLK(NULL, "emif2_fck", &emif2_fck, CK_44XX),
+ CLK(NULL, "fdif_fck", &fdif_fck, CK_44XX),
+ CLK(NULL, "fpka_fck", &fpka_fck, CK_44XX),
+ CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_44XX),
+ CLK(NULL, "gpio1_ick", &gpio1_ick, CK_44XX),
+ CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_44XX),
+ CLK(NULL, "gpio2_ick", &gpio2_ick, CK_44XX),
+ CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_44XX),
+ CLK(NULL, "gpio3_ick", &gpio3_ick, CK_44XX),
+ CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_44XX),
+ CLK(NULL, "gpio4_ick", &gpio4_ick, CK_44XX),
+ CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_44XX),
+ CLK(NULL, "gpio5_ick", &gpio5_ick, CK_44XX),
+ CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_44XX),
+ CLK(NULL, "gpio6_ick", &gpio6_ick, CK_44XX),
+ CLK(NULL, "gpmc_ick", &gpmc_ick, CK_44XX),
+ CLK(NULL, "gpu_fck", &gpu_fck, CK_44XX),
+ CLK("omap2_hdq.0", "fck", &hdq1w_fck, CK_44XX),
+ CLK(NULL, "hsi_fck", &hsi_fck, CK_44XX),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_44XX),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_44XX),
+ CLK("omap_i2c.3", "fck", &i2c3_fck, CK_44XX),
+ CLK("omap_i2c.4", "fck", &i2c4_fck, CK_44XX),
+ CLK(NULL, "ipu_fck", &ipu_fck, CK_44XX),
+ CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_44XX),
+ CLK(NULL, "iss_fck", &iss_fck, CK_44XX),
+ CLK(NULL, "iva_fck", &iva_fck, CK_44XX),
+ CLK(NULL, "kbd_fck", &kbd_fck, CK_44XX),
+ CLK(NULL, "l3_instr_ick", &l3_instr_ick, CK_44XX),
+ CLK(NULL, "l3_main_3_ick", &l3_main_3_ick, CK_44XX),
+ CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_44XX),
+ CLK(NULL, "mcasp_fck", &mcasp_fck, CK_44XX),
+ CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_44XX),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_44XX),
+ CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_44XX),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_44XX),
+ CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_44XX),
+ CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_44XX),
+ CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_44XX),
+ CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_44XX),
+ CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_44XX),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_44XX),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_44XX),
+ CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_44XX),
+ CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_44XX),
+ CLK("omap_hsmmc.0", "fck", &mmc1_fck, CK_44XX),
+ CLK("omap_hsmmc.1", "fck", &mmc2_fck, CK_44XX),
+ CLK("omap_hsmmc.2", "fck", &mmc3_fck, CK_44XX),
+ CLK("omap_hsmmc.3", "fck", &mmc4_fck, CK_44XX),
+ CLK("omap_hsmmc.4", "fck", &mmc5_fck, CK_44XX),
+ CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_44XX),
+ CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_44XX),
+ CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_44XX),
+ CLK("omap_rng", "ick", &rng_ick, CK_44XX),
+ CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_44XX),
+ CLK(NULL, "sl2if_ick", &sl2if_ick, CK_44XX),
+ CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_44XX),
+ CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_44XX),
+ CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_44XX),
+ CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_44XX),
+ CLK(NULL, "slimbus1_fck", &slimbus1_fck, CK_44XX),
+ CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_44XX),
+ CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_44XX),
+ CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_44XX),
+ CLK(NULL, "slimbus2_fck", &slimbus2_fck, CK_44XX),
+ CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_44XX),
+ CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_44XX),
+ CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_44XX),
+ CLK(NULL, "gpt1_fck", &timer1_fck, CK_44XX),
+ CLK(NULL, "gpt10_fck", &timer10_fck, CK_44XX),
+ CLK(NULL, "gpt11_fck", &timer11_fck, CK_44XX),
+ CLK(NULL, "gpt2_fck", &timer2_fck, CK_44XX),
+ CLK(NULL, "gpt3_fck", &timer3_fck, CK_44XX),
+ CLK(NULL, "gpt4_fck", &timer4_fck, CK_44XX),
+ CLK(NULL, "gpt5_fck", &timer5_fck, CK_44XX),
+ CLK(NULL, "gpt6_fck", &timer6_fck, CK_44XX),
+ CLK(NULL, "gpt7_fck", &timer7_fck, CK_44XX),
+ CLK(NULL, "gpt8_fck", &timer8_fck, CK_44XX),
+ CLK(NULL, "gpt9_fck", &timer9_fck, CK_44XX),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_44XX),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_44XX),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_44XX),
+ CLK(NULL, "uart4_fck", &uart4_fck, CK_44XX),
+ CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_44XX),
+ CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_44XX),
+ CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_44XX),
+ CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_44XX),
+ CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_44XX),
+ CLK(NULL, "usb_host_hs_utmi_p2_clk", &usb_host_hs_utmi_p2_clk, CK_44XX),
+ CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_44XX),
+ CLK(NULL, "usb_host_hs_hsic480m_p1_clk", &usb_host_hs_hsic480m_p1_clk, CK_44XX),
+ CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_44XX),
+ CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_44XX),
+ CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_44XX),
+ CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_44XX),
+ CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_44XX),
+ CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_44XX),
+ CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_44XX),
+ CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_44XX),
+ CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_44XX),
+ CLK(NULL, "usb_phy_cm_clk32k", &usb_phy_cm_clk32k, CK_44XX),
+ CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_44XX),
+ CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_44XX),
+ CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_44XX),
+ CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_44XX),
+ CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_44XX),
+ CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_44XX),
+ CLK(NULL, "usim_ck", &usim_ck, CK_44XX),
+ CLK(NULL, "usim_fclk", &usim_fclk, CK_44XX),
+ CLK(NULL, "usim_fck", &usim_fck, CK_44XX),
+ CLK("omap_wdt", "fck", &wd_timer2_fck, CK_44XX),
+ CLK(NULL, "mailboxes_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_44XX),
+ CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_44XX),
+ CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck, CK_44XX),
+ CLK(NULL, "gpmc_ck", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt1_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt2_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt3_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt4_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt5_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt6_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt7_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt8_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt9_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt10_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "gpt11_ick", &dummy_ck, CK_44XX),
+ CLK("omap_i2c.1", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_i2c.2", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_i2c.3", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_i2c.4", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_hsmmc.0", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_hsmmc.1", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_hsmmc.2", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_hsmmc.3", "ick", &dummy_ck, CK_44XX),
+ CLK("omap_hsmmc.4", "ick", &dummy_ck, CK_44XX),
+ CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_44XX),
+ CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_44XX),
+ CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_44XX),
+ CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_44XX),
+ CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_44XX),
+ CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_44XX),
+ CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_44XX),
+ CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "uart1_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "uart2_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "uart3_ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "uart4_ick", &dummy_ck, CK_44XX),
+ CLK("omap_wdt", "ick", &dummy_ck, CK_44XX),
+ CLK(NULL, "auxclk0_src_ck", &auxclk0_src_ck, CK_44XX),
+ CLK(NULL, "auxclk0_ck", &auxclk0_ck, CK_44XX),
+ CLK(NULL, "auxclk1_src_ck", &auxclk1_src_ck, CK_44XX),
+ CLK(NULL, "auxclk1_ck", &auxclk1_ck, CK_44XX),
+ CLK(NULL, "auxclk2_src_ck", &auxclk2_src_ck, CK_44XX),
+ CLK(NULL, "auxclk2_ck", &auxclk2_ck, CK_44XX),
+ CLK(NULL, "auxclk3_src_ck", &auxclk3_src_ck, CK_44XX),
+ CLK(NULL, "auxclk3_ck", &auxclk3_ck, CK_44XX),
+ CLK(NULL, "auxclk4_src_ck", &auxclk4_src_ck, CK_44XX),
+ CLK(NULL, "auxclk4_ck", &auxclk4_ck, CK_44XX),
+ CLK(NULL, "auxclk5_src_ck", &auxclk5_src_ck, CK_44XX),
+ CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_44XX),
+ CLK(NULL, "auxclkreq0_ck", &auxclkreq0_ck, CK_44XX),
+ CLK(NULL, "auxclkreq1_ck", &auxclkreq1_ck, CK_44XX),
+ CLK(NULL, "auxclkreq2_ck", &auxclkreq2_ck, CK_44XX),
+ CLK(NULL, "auxclkreq3_ck", &auxclkreq3_ck, CK_44XX),
+ CLK(NULL, "auxclkreq4_ck", &auxclkreq4_ck, CK_44XX),
+ CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_44XX),
+ CLK(NULL, "smp_twd", &smp_twd, CK_44XX),
+};
+
+#define L3_OPP50_RATE 100000000
+#define DPLL_CORE_M3_OPP50_RATE 200000000
+#define DPLL_CORE_M3_OPP100_RATE 320000000
+#define DPLL_CORE_M6_OPP50_RATE 200000000
+#define DPLL_CORE_M6_OPP100_RATE 266600000
+#define DPLL_CORE_M7_OPP50_RATE 133333333
+#define DPLL_CORE_M7_OPP100_RATE 266666666
+#define DPLL_PER_M3_OPP50_RATE 192000000
+#define DPLL_PER_M3_OPP100_RATE 256000000
+#define DPLL_PER_M6_OPP50_RATE 192000000
+#define DPLL_PER_M6_OPP100_RATE 384000000
+
+static long omap4_virt_l3_round_rate(struct clk *clk, unsigned long rate)
+{
+ long parent_rate;
+
+ if (!clk || !clk->parent)
+ return 0;
+
+ if (clk->parent->round_rate) {
+ parent_rate = clk->parent->round_rate(clk, rate * 2);
+ if (parent_rate)
+ return parent_rate / 2;
+ }
+ return 0;
+}
+
+static unsigned long omap4_virt_l3_recalc(struct clk *clk)
+{
+ if (!clk || !clk->parent)
+ return 0;
+
+ return clk->parent->rate / 2;
+}
+
+static int omap4_clksel_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (!clk->set_rate || !clk->round_rate)
+ return ret;
+
+ rate = clk->round_rate(clk, rate);
+ if (rate) {
+ ret = clk->set_rate(clk, rate);
+ if (!ret)
+ propagate_rate(clk);
+ }
+ return ret;
+}
+
+struct virt_l3_ck_deps {
+ unsigned long core_m3_rate;
+ unsigned long core_m6_rate;
+ unsigned long core_m7_rate;
+ unsigned long per_m3_rate;
+ unsigned long per_m6_rate;
+};
+
+#define NO_OF_L3_OPPS 2
+#define L3_OPP_50_INDEX 0
+#define L3_OPP_100_INDEX 1
+
+static struct virt_l3_ck_deps omap4_virt_l3_clk_deps[NO_OF_L3_OPPS] = {
+ { /* OPP 50 */
+ .core_m3_rate = DPLL_CORE_M3_OPP50_RATE,
+ .core_m6_rate = DPLL_CORE_M6_OPP50_RATE,
+ .core_m7_rate = DPLL_CORE_M7_OPP50_RATE,
+ .per_m3_rate = DPLL_PER_M3_OPP50_RATE,
+ .per_m6_rate = DPLL_PER_M6_OPP50_RATE,
+ },
+ { /* OPP 100 */
+ .core_m3_rate = DPLL_CORE_M3_OPP100_RATE,
+ .core_m6_rate = DPLL_CORE_M3_OPP100_RATE,
+ .core_m7_rate = DPLL_CORE_M7_OPP100_RATE,
+ .per_m3_rate = DPLL_PER_M3_OPP100_RATE,
+ .per_m6_rate = DPLL_PER_M6_OPP100_RATE,
+ },
+};
+
+static int omap4_virt_l3_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct virt_l3_ck_deps *l3_deps;
+
+ if (rate <= L3_OPP50_RATE)
+ l3_deps = &omap4_virt_l3_clk_deps[L3_OPP_50_INDEX];
+ else
+ l3_deps = &omap4_virt_l3_clk_deps[L3_OPP_100_INDEX];
+
+ omap4_clksel_set_rate(&dpll_core_m3x2_ck, l3_deps->core_m3_rate);
+ omap4_clksel_set_rate(&dpll_core_m6x2_ck, l3_deps->core_m6_rate);
+ omap4_clksel_set_rate(&dpll_core_m7x2_ck, l3_deps->core_m7_rate);
+ omap4_clksel_set_rate(&dpll_per_m3x2_ck, l3_deps->per_m3_rate);
+ omap4_clksel_set_rate(&dpll_per_m6x2_ck, l3_deps->per_m6_rate);
+ omap4_clksel_set_rate(&dpll_core_m5x2_ck, rate * 2);
+
+ clk->rate = rate;
+ return 0;
+}
int __init omap4xxx_clk_init(void)
{
struct omap_clk *c;
- u32 cpu_clkflg;
+ u32 cpu_clkflg = 0;
- if (cpu_is_omap44xx()) {
- cpu_mask = RATE_IN_4430;
+ if (cpu_is_omap443x()) {
+ cpu_mask = RATE_IN_443X;
cpu_clkflg = CK_443X;
+ } else if (cpu_is_omap446x()) {
+ cpu_mask = RATE_IN_446X;
+ cpu_clkflg = CK_446X;
}
clk_init(&omap2_clk_functions);
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 6cb6c03..b98a972 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -795,6 +795,27 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
arch_clkdm->clkdm_deny_idle(clkdm);
}
+/**
+ * clkdm_is_idle - Check if the clkdm hwsup/autoidle is enabled
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if the clockdomain is in hardware-supervised
+ * idle mode, or 0 otherwise.
+ *
+ */
+int clkdm_is_idle(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_is_idle)
+ return -EINVAL;
+
+ pr_debug("clockdomain: reading idle state for %s\n", clkdm->name);
+
+ return arch_clkdm->clkdm_is_idle(clkdm);
+}
+
/* Clockdomain-to-clock framework interface code */
@@ -825,7 +846,12 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable)
return -EINVAL;
- if (atomic_inc_return(&clkdm->usecount) > 1)
+ /*
+ * For arch's with no autodeps, clkcm_clk_enable
+ * should be called for every clock instance that is
+ * enabled, so the clkdm can be force woken up.
+ */
+ if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps)
return 0;
/* Clockdomain now has one enabled downstream clock */
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 5823584..085ed82 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -138,6 +138,7 @@ struct clockdomain {
* @clkdm_wakeup: Force a clockdomain to wakeup
* @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
* @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
+ * @clkdm_is_idle: Check if hw supervised idle transitions are enabled
* @clkdm_clk_enable: Put the clkdm in right state for a clock enable
* @clkdm_clk_disable: Put the clkdm in right state for a clock disable
*/
@@ -154,6 +155,7 @@ struct clkdm_ops {
int (*clkdm_wakeup)(struct clockdomain *clkdm);
void (*clkdm_allow_idle)(struct clockdomain *clkdm);
void (*clkdm_deny_idle)(struct clockdomain *clkdm);
+ int (*clkdm_is_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm);
};
@@ -177,6 +179,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
void clkdm_allow_idle(struct clockdomain *clkdm);
void clkdm_deny_idle(struct clockdomain *clkdm);
+int clkdm_is_idle(struct clockdomain *clkdm);
int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 48d0db7..db49baa 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -13,6 +13,7 @@
*/
#include <linux/types.h>
+#include <linux/errno.h>
#include <plat/prcm.h>
#include "prm.h"
#include "prm2xxx_3xxx.h"
@@ -146,6 +147,15 @@ static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
_clkdm_del_autodeps(clkdm);
}
+static int omap2_clkdm_is_idle(struct clockdomain *clkdm)
+{
+ if (!clkdm->clktrctrl_mask)
+ return -1;
+
+ return omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
static void _enable_hwsup(struct clockdomain *clkdm)
{
if (cpu_is_omap24xx())
@@ -252,6 +262,7 @@ struct clkdm_ops omap2_clkdm_operations = {
.clkdm_wakeup = omap2_clkdm_wakeup,
.clkdm_allow_idle = omap2_clkdm_allow_idle,
.clkdm_deny_idle = omap2_clkdm_deny_idle,
+ .clkdm_is_idle = omap2_clkdm_is_idle,
.clkdm_clk_enable = omap2_clkdm_clk_enable,
.clkdm_clk_disable = omap2_clkdm_clk_disable,
};
@@ -269,6 +280,7 @@ struct clkdm_ops omap3_clkdm_operations = {
.clkdm_wakeup = omap3_clkdm_wakeup,
.clkdm_allow_idle = omap3_clkdm_allow_idle,
.clkdm_deny_idle = omap3_clkdm_deny_idle,
+ .clkdm_is_idle = omap2_clkdm_is_idle,
.clkdm_clk_enable = omap2_clkdm_clk_enable,
.clkdm_clk_disable = omap2_clkdm_clk_disable,
};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index a1a4ecd..5024e63 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -93,15 +93,16 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
clkdm->cm_inst, clkdm->clkdm_offs);
}
-static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+static int omap4_clkdm_is_idle(struct clockdomain *clkdm)
{
- bool hwsup = false;
-
- hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst, clkdm->clkdm_offs);
+ return omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+}
- if (!hwsup)
- clkdm_wakeup(clkdm);
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ /* For every clock enable, force wakeup the clkdm */
+ clkdm_wakeup(clkdm);
return 0;
}
@@ -132,6 +133,7 @@ struct clkdm_ops omap4_clkdm_operations = {
.clkdm_wakeup = omap4_clkdm_wakeup,
.clkdm_allow_idle = omap4_clkdm_allow_idle,
.clkdm_deny_idle = omap4_clkdm_deny_idle,
+ .clkdm_is_idle = omap4_clkdm_is_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable,
};
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 52fbe7a..8d1a061 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -35,55 +35,55 @@
static struct clkdm_dep ducati_wkup_sleep_deps[] = {
{
.clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_gfx_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "tesla_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -91,15 +91,15 @@ static struct clkdm_dep ducati_wkup_sleep_deps[] = {
static struct clkdm_dep iss_wkup_sleep_deps[] = {
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -107,11 +107,11 @@ static struct clkdm_dep iss_wkup_sleep_deps[] = {
static struct clkdm_dep ivahd_wkup_sleep_deps[] = {
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -119,35 +119,35 @@ static struct clkdm_dep ivahd_wkup_sleep_deps[] = {
static struct clkdm_dep l3_d2d_wkup_sleep_deps[] = {
{
.clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -155,47 +155,47 @@ static struct clkdm_dep l3_d2d_wkup_sleep_deps[] = {
static struct clkdm_dep l3_dma_wkup_sleep_deps[] = {
{
.clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ducati_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -203,15 +203,15 @@ static struct clkdm_dep l3_dma_wkup_sleep_deps[] = {
static struct clkdm_dep l3_dss_wkup_sleep_deps[] = {
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -219,15 +219,15 @@ static struct clkdm_dep l3_dss_wkup_sleep_deps[] = {
static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = {
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -235,31 +235,31 @@ static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = {
static struct clkdm_dep l3_init_wkup_sleep_deps[] = {
{
.clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -267,15 +267,15 @@ static struct clkdm_dep l3_init_wkup_sleep_deps[] = {
static struct clkdm_dep l4_secure_wkup_sleep_deps[] = {
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -283,59 +283,59 @@ static struct clkdm_dep l4_secure_wkup_sleep_deps[] = {
static struct clkdm_dep mpuss_wkup_sleep_deps[] = {
{
.clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ducati_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_gfx_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "tesla_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -343,39 +343,39 @@ static struct clkdm_dep mpuss_wkup_sleep_deps[] = {
static struct clkdm_dep tesla_wkup_sleep_deps[] = {
{
.clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{
.clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX)
},
{ NULL },
};
@@ -387,7 +387,7 @@ static struct clockdomain l4_cefuse_44xx_clkdm = {
.cm_inst = OMAP4430_CM2_CEFUSE_INST,
.clkdm_offs = OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l4_cfg_44xx_clkdm = {
@@ -398,7 +398,7 @@ static struct clockdomain l4_cfg_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_L4CFG_CDOFFS,
.dep_bit = OMAP4430_L4CFG_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain tesla_44xx_clkdm = {
@@ -411,7 +411,7 @@ static struct clockdomain tesla_44xx_clkdm = {
.wkdep_srcs = tesla_wkup_sleep_deps,
.sleepdep_srcs = tesla_wkup_sleep_deps,
.flags = CLKDM_CAN_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_gfx_44xx_clkdm = {
@@ -424,7 +424,7 @@ static struct clockdomain l3_gfx_44xx_clkdm = {
.wkdep_srcs = l3_gfx_wkup_sleep_deps,
.sleepdep_srcs = l3_gfx_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain ivahd_44xx_clkdm = {
@@ -437,7 +437,7 @@ static struct clockdomain ivahd_44xx_clkdm = {
.wkdep_srcs = ivahd_wkup_sleep_deps,
.sleepdep_srcs = ivahd_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l4_secure_44xx_clkdm = {
@@ -450,7 +450,7 @@ static struct clockdomain l4_secure_44xx_clkdm = {
.wkdep_srcs = l4_secure_wkup_sleep_deps,
.sleepdep_srcs = l4_secure_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l4_per_44xx_clkdm = {
@@ -461,7 +461,7 @@ static struct clockdomain l4_per_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_L4PER_L4PER_CDOFFS,
.dep_bit = OMAP4430_L4PER_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain abe_44xx_clkdm = {
@@ -472,7 +472,7 @@ static struct clockdomain abe_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM1_ABE_ABE_CDOFFS,
.dep_bit = OMAP4430_ABE_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_instr_44xx_clkdm = {
@@ -481,7 +481,7 @@ static struct clockdomain l3_instr_44xx_clkdm = {
.prcm_partition = OMAP4430_CM2_PARTITION,
.cm_inst = OMAP4430_CM2_CORE_INST,
.clkdm_offs = OMAP4430_CM2_CORE_L3INSTR_CDOFFS,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_init_44xx_clkdm = {
@@ -493,8 +493,8 @@ static struct clockdomain l3_init_44xx_clkdm = {
.dep_bit = OMAP4430_L3INIT_STATDEP_SHIFT,
.wkdep_srcs = l3_init_wkup_sleep_deps,
.sleepdep_srcs = l3_init_wkup_sleep_deps,
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .flags = CLKDM_CAN_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain mpuss_44xx_clkdm = {
@@ -506,7 +506,7 @@ static struct clockdomain mpuss_44xx_clkdm = {
.wkdep_srcs = mpuss_wkup_sleep_deps,
.sleepdep_srcs = mpuss_wkup_sleep_deps,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain mpu0_44xx_clkdm = {
@@ -516,7 +516,7 @@ static struct clockdomain mpu0_44xx_clkdm = {
.cm_inst = OMAP4430_PRCM_MPU_CPU0_INST,
.clkdm_offs = OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain mpu1_44xx_clkdm = {
@@ -526,7 +526,7 @@ static struct clockdomain mpu1_44xx_clkdm = {
.cm_inst = OMAP4430_PRCM_MPU_CPU1_INST,
.clkdm_offs = OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_emif_44xx_clkdm = {
@@ -537,7 +537,7 @@ static struct clockdomain l3_emif_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_MEMIF_CDOFFS,
.dep_bit = OMAP4430_MEMIF_STATDEP_SHIFT,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l4_ao_44xx_clkdm = {
@@ -547,7 +547,7 @@ static struct clockdomain l4_ao_44xx_clkdm = {
.cm_inst = OMAP4430_CM2_ALWAYS_ON_INST,
.clkdm_offs = OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain ducati_44xx_clkdm = {
@@ -560,7 +560,7 @@ static struct clockdomain ducati_44xx_clkdm = {
.wkdep_srcs = ducati_wkup_sleep_deps,
.sleepdep_srcs = ducati_wkup_sleep_deps,
.flags = CLKDM_CAN_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_2_44xx_clkdm = {
@@ -571,7 +571,7 @@ static struct clockdomain l3_2_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_L3_2_CDOFFS,
.dep_bit = OMAP4430_L3_2_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_1_44xx_clkdm = {
@@ -582,7 +582,7 @@ static struct clockdomain l3_1_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_L3_1_CDOFFS,
.dep_bit = OMAP4430_L3_1_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_d2d_44xx_clkdm = {
@@ -594,7 +594,7 @@ static struct clockdomain l3_d2d_44xx_clkdm = {
.wkdep_srcs = l3_d2d_wkup_sleep_deps,
.sleepdep_srcs = l3_d2d_wkup_sleep_deps,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain iss_44xx_clkdm = {
@@ -605,8 +605,8 @@ static struct clockdomain iss_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
.wkdep_srcs = iss_wkup_sleep_deps,
.sleepdep_srcs = iss_wkup_sleep_deps,
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .flags = CLKDM_CAN_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_dss_44xx_clkdm = {
@@ -619,7 +619,7 @@ static struct clockdomain l3_dss_44xx_clkdm = {
.wkdep_srcs = l3_dss_wkup_sleep_deps,
.sleepdep_srcs = l3_dss_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l4_wkup_44xx_clkdm = {
@@ -630,7 +630,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = {
.clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS,
.dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain emu_sys_44xx_clkdm = {
@@ -640,7 +640,7 @@ static struct clockdomain emu_sys_44xx_clkdm = {
.cm_inst = OMAP4430_PRM_EMU_CM_INST,
.clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain l3_dma_44xx_clkdm = {
@@ -652,7 +652,7 @@ static struct clockdomain l3_dma_44xx_clkdm = {
.wkdep_srcs = l3_dma_wkup_sleep_deps,
.sleepdep_srcs = l3_dma_wkup_sleep_deps,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct clockdomain *clockdomains_omap44xx[] __initdata = {
diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h
index 9d47a05..4c4cbfa 100644
--- a/arch/arm/mach-omap2/cm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-44xx.h
@@ -106,6 +106,10 @@
#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT 9
#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK (1 << 9)
+/* Used by CM_L4CFG_CLKSTCTRL */
+#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_SHIFT 9
+#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_MASK (1 << 9)
+
/* Used by CM_CEFUSE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9
#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9)
@@ -418,6 +422,10 @@
#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT 11
#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK (1 << 11)
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_SHIFT 13
+#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_MASK (1 << 13)
+
/*
* Used by CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL,
* CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
@@ -449,6 +457,10 @@
#define OMAP4430_CLKSEL_60M_SHIFT 24
#define OMAP4430_CLKSEL_60M_MASK (1 << 24)
+/* Used by CM_MPU_MPU_CLKCTRL */
+#define OMAP4460_CLKSEL_ABE_DIV_MODE_SHIFT 25
+#define OMAP4460_CLKSEL_ABE_DIV_MODE_MASK (1 << 25)
+
/* Used by CM1_ABE_AESS_CLKCTRL */
#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24
#define OMAP4430_CLKSEL_AESS_FCLK_MASK (1 << 24)
@@ -468,6 +480,10 @@
#define OMAP4430_CLKSEL_DIV_SHIFT 24
#define OMAP4430_CLKSEL_DIV_MASK (1 << 24)
+/* Used by CM_MPU_MPU_CLKCTRL */
+#define OMAP4460_CLKSEL_EMIF_DIV_MODE_SHIFT 24
+#define OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK (1 << 24)
+
/* Used by CM_CAM_FDIF_CLKCTRL */
#define OMAP4430_CLKSEL_FCLK_SHIFT 24
#define OMAP4430_CLKSEL_FCLK_MASK (0x3 << 24)
@@ -572,6 +588,14 @@
#define OMAP4430_D2D_STATDEP_SHIFT 18
#define OMAP4430_D2D_STATDEP_MASK (1 << 18)
+/* Used by CM_CLKSEL_DPLL_MPU */
+#define OMAP4460_DCC_COUNT_MAX_SHIFT 24
+#define OMAP4460_DCC_COUNT_MAX_MASK (0xff << 24)
+
+/* Used by CM_CLKSEL_DPLL_MPU */
+#define OMAP4460_DCC_EN_SHIFT 22
+#define OMAP4460_DCC_EN_MASK (1 << 22)
+
/*
* Used by CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
* CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE, CM_SSC_DELTAMSTEP_DPLL_DDRPHY,
@@ -1204,6 +1228,10 @@
#define OMAP4430_MODULEMODE_SHIFT 0
#define OMAP4430_MODULEMODE_MASK (0x3 << 0)
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4460_MPU_DYNDEP_SHIFT 19
+#define OMAP4460_MPU_DYNDEP_MASK (1 << 19)
+
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9
#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK (1 << 9)
@@ -1298,6 +1326,10 @@
#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10
#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK (1 << 10)
+/* Used by CM_WKUP_BANDGAP_CLKCTRL */
+#define OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT 8
+#define OMAP4460_OPTFCLKEN_TS_FCLK_MASK (1 << 8)
+
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11
#define OMAP4430_OPTFCLKEN_TV_CLK_MASK (1 << 11)
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
index 3f20cbb..4ffcb54 100644
--- a/arch/arm/mach-omap2/common.c
+++ b/arch/arm/mach-omap2/common.c
@@ -127,6 +127,7 @@ static struct omap_globals omap4_globals = {
.tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
.ctrl = OMAP443X_SCM_BASE,
.ctrl_pad = OMAP443X_CTRL_BASE,
+ .ctrl_wk_pad = OMAP443X_CTRL_WK_BASE,
.prm = OMAP4430_PRM_BASE,
.cm = OMAP4430_CM_BASE,
.cm2 = OMAP4430_CM2_BASE,
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index da53ba3..5faf166 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -32,6 +32,7 @@
static void __iomem *omap2_ctrl_base;
static void __iomem *omap4_ctrl_pad_base;
+static void __iomem *omap4_ctrl_wk_pad_base;
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
struct omap3_scratchpad {
@@ -146,6 +147,7 @@ static struct omap3_control_regs control_context;
#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
#define OMAP4_CTRL_PAD_REGADDR(reg) (omap4_ctrl_pad_base + (reg))
+#define OMAP4_CTRL_WK_PAD_REGADDR(reg) (omap4_ctrl_wk_pad_base + (reg))
void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
{
@@ -160,6 +162,17 @@ void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
omap4_ctrl_pad_base = ioremap(omap2_globals->ctrl_pad, SZ_4K);
WARN_ON(!omap4_ctrl_pad_base);
}
+
+ /*
+ * static mapping, never released. omap4 Wakeup pad is seperate
+ * from the core, hence need to be mapped individually.
+ */
+ if (omap2_globals->ctrl_wk_pad) {
+ omap4_ctrl_wk_pad_base = ioremap(omap2_globals->ctrl_wk_pad,
+ SZ_4K);
+ WARN_ON(!omap4_ctrl_wk_pad_base);
+ }
+
}
void __iomem *omap_ctrl_base_get(void)
@@ -204,16 +217,66 @@ void omap_ctrl_writel(u32 val, u16 offset)
* registers. This APIs will work only for OMAP4
*/
+u8 omap4_ctrl_pad_readb(u16 offset)
+{
+ return __raw_readb(OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
+u16 omap4_ctrl_pad_readw(u16 offset)
+{
+ return __raw_readw(OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
u32 omap4_ctrl_pad_readl(u16 offset)
{
return __raw_readl(OMAP4_CTRL_PAD_REGADDR(offset));
}
+void omap4_ctrl_pad_writeb(u8 val, u16 offset)
+{
+ __raw_writeb(val, OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
+void omap4_ctrl_pad_writew(u16 val, u16 offset)
+{
+ __raw_writew(val, OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
void omap4_ctrl_pad_writel(u32 val, u16 offset)
{
__raw_writel(val, OMAP4_CTRL_PAD_REGADDR(offset));
}
+u8 omap4_ctrl_wk_pad_readb(u16 offset)
+{
+ return __raw_readb(OMAP4_CTRL_WK_PAD_REGADDR(offset));
+}
+
+u16 omap4_ctrl_wk_pad_readw(u16 offset)
+{
+ return __raw_readw(OMAP4_CTRL_WK_PAD_REGADDR(offset));
+}
+
+u32 omap4_ctrl_wk_pad_readl(u16 offset)
+{
+ return __raw_readl(OMAP4_CTRL_WK_PAD_REGADDR(offset));
+}
+
+void omap4_ctrl_wk_pad_writeb(u8 val, u16 offset)
+{
+ __raw_writeb(val, OMAP4_CTRL_WK_PAD_REGADDR(offset));
+}
+
+void omap4_ctrl_wk_pad_writew(u16 val, u16 offset)
+{
+ __raw_writew(val, OMAP4_CTRL_WK_PAD_REGADDR(offset));
+}
+
+void omap4_ctrl_wk_pad_writel(u32 val, u16 offset)
+{
+ __raw_writel(val, OMAP4_CTRL_WK_PAD_REGADDR(offset));
+}
+
#ifdef CONFIG_ARCH_OMAP3
/**
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a016c8b..1aa7632 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -195,6 +195,7 @@
#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A
/* AM35XX only CONTROL_GENERAL register offsets */
#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
@@ -338,6 +339,14 @@
#define AM35XX_HECC_SW_RST BIT(3)
#define AM35XX_VPFE_PCLK_SW_RST BIT(4)
+/* CONTROL_PADCONF_X bits */
+#define OMAP44XX_PADCONF_WAKEUPEVENT0 (1 << 15)
+#define OMAP44XX_PADCONF_WAKEUPEVENT1 (1 << 30)
+#define OMAP44XX_PADCONF_WAKEUPENABLE0 (1 << 14)
+#define OMAP44XX_PADCONF_WAKEUPENABLE1 (1 << 31)
+#define OMAP44XX_PADCONF_OFFMODEENABLE0 (1 << 9)
+#define OMAP44XX_PADCONF_OFFMODEENABLE1 (1 << 25)
+
/*
* CONTROL OMAP STATUS register to identify OMAP3 features
*/
@@ -378,11 +387,21 @@ extern void __iomem *omap_ctrl_base_get(void);
extern u8 omap_ctrl_readb(u16 offset);
extern u16 omap_ctrl_readw(u16 offset);
extern u32 omap_ctrl_readl(u16 offset);
+extern u8 omap4_ctrl_pad_readb(u16 offset);
+extern u16 omap4_ctrl_pad_readw(u16 offset);
extern u32 omap4_ctrl_pad_readl(u16 offset);
+extern u8 omap4_ctrl_wk_pad_readb(u16 offset);
+extern u16 omap4_ctrl_wk_pad_readw(u16 offset);
+extern u32 omap4_ctrl_wk_pad_readl(u16 offset);
extern void omap_ctrl_writeb(u8 val, u16 offset);
extern void omap_ctrl_writew(u16 val, u16 offset);
extern void omap_ctrl_writel(u32 val, u16 offset);
+extern void omap4_ctrl_pad_writeb(u8 val, u16 offset);
+extern void omap4_ctrl_pad_writew(u16 val, u16 offset);
extern void omap4_ctrl_pad_writel(u32 val, u16 offset);
+extern void omap4_ctrl_wk_pad_writeb(u8 val, u16 offset);
+extern void omap4_ctrl_wk_pad_writew(u16 val, u16 offset);
+extern void omap4_ctrl_wk_pad_writel(u32 val, u16 offset);
extern void omap3_save_scratchpad_contents(void);
extern void omap3_clear_scratchpad_contents(void);
@@ -400,11 +419,21 @@ extern int omap3_ctrl_save_padconf(void);
#define omap_ctrl_readb(x) 0
#define omap_ctrl_readw(x) 0
#define omap_ctrl_readl(x) 0
-#define omap4_ctrl_pad_readl(x) 0
+#define omap4_ctrl_pad_readb(x) 0
+#define omap4_ctrl_pad_readw(x) 0
+#define omap4_ctrl_pad_readl(x) 0
+#define omap4_ctrl_wk_pad_readb(x) 0
+#define omap4_ctrl_wk_pad_readw(x) 0
+#define omap4_ctrl_wk_pad_readl(x) 0
#define omap_ctrl_writeb(x, y) WARN_ON(1)
#define omap_ctrl_writew(x, y) WARN_ON(1)
#define omap_ctrl_writel(x, y) WARN_ON(1)
+#define omap4_ctrl_pad_writeb(x, y) WARN_ON(1)
+#define omap4_ctrl_pad_writew(x, y) WARN_ON(1)
#define omap4_ctrl_pad_writel(x, y) WARN_ON(1)
+#define omap4_ctrl_wk_pad_writeb(x, y) WARN_ON(1)
+#define omap4_ctrl_wk_pad_writew(x, y) WARN_ON(1)
+#define omap4_ctrl_wk_pad_writel(x, y) WARN_ON(1)
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
new file mode 100644
index 0000000..9f085da
--- /dev/null
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -0,0 +1,381 @@
+/*
+ * OMAP4 CPU idle Routines
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.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/sched.h>
+#include <linux/cpuidle.h>
+#include <linux/clockchips.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/omap4-common.h>
+
+#include <plat/gpio.h>
+
+#include "pm.h"
+#include "prm.h"
+
+#ifdef CONFIG_CPU_IDLE
+
+#define OMAP4_MAX_STATES 4
+
+#define CPUIDLE_FLAG_CHECK_BM 0x10000 /* use omap4_enter_idle_bm() */
+
+/* C1 - CPU0 WFI + CPU1 OFF + MPU ON + CORE ON */
+#define OMAP4_STATE_C1 0
+/* C2 - CPU0 INA + CPU1 OFF + MPU INA + CORE INA */
+#define OMAP4_STATE_C2 1
+/* C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE CSWR */
+#define OMAP4_STATE_C3 2
+/* C4 - CPU0 OFF + CPU1 OFF + MPU RET + CORE CSWR */
+#define OMAP4_STATE_C4 3
+
+struct omap4_processor_cx {
+ u8 valid;
+ u8 type;
+ u32 exit_latency;
+ u32 target_residency;
+ u32 cpu0_state;
+ u32 mpu_state;
+ u32 mpu_logic_state;
+ u32 core_state;
+ u32 core_logic_state;
+ u32 flags;
+ const char *desc;
+};
+
+struct omap4_processor_cx omap4_power_states[OMAP4_MAX_STATES];
+static struct powerdomain *mpu_pd, *cpu1_pd, *core_pd;
+static int needs_state_data_update;
+static unsigned int state_flags = CPUIDLE_FLAG_IGNORE;
+
+/*
+ * FIXME: Full latency numbers needs to be updated as part of
+ * cpuidle CORE retention support.
+ * Currently only MPUSS latency numbers are added based on
+ * measurements done internally. The numbers for MPUSS are
+ * not board dependent and hence set directly here instead of
+ * passing it from board files.
+ */
+static struct cpuidle_params cpuidle_params_table[] = {
+ /* C1 - CPU0 WFI + CPU1 OFF + MPU ON + CORE ON */
+ {.exit_latency = 2 + 2, .target_residency = 5, .valid = 1},
+ /* C2 - CPU0 INA + CPU1 OFF + MPU INA + CORE INA */
+ {.exit_latency = 140 + 160, .target_residency = 300, .valid = 1},
+ /* C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE CSWR */
+ {.exit_latency = 1516 + 3220, .target_residency = 15000, .valid = 1},
+ /* C4 - CPU0 OFF + CPU1 OFF + MPU OSWR + CORE OSWR */
+ {.exit_latency = 1644 + 3298, .target_residency = 39000, .valid = 0},
+};
+
+static bool omap4_idle_bm_busy(void)
+{
+ if (!omap4_can_sleep())
+ return true;
+ return false;
+}
+
+/**
+ * omap4_prepare_idle - Update C-state parameters dynamically
+ * @dev: cpuidle device
+ *
+ * Called from the CPUidle framework to prepare the device
+ * for idle before before calling the governor's select function.
+ */
+static int omap4_prepare_idle(struct cpuidle_device *dev)
+{
+ int i, ret = 0;
+
+ if (!needs_state_data_update)
+ return ret;
+
+ /*
+ * Update the C-state flags based on CPU1 online
+ * or offline state. On OMAP4, the low power C-states
+ * are made available when only CPU1 is offline.
+ */
+ for (i = OMAP4_STATE_C2; i < OMAP4_MAX_STATES; i++)
+ dev->states[i].flags = state_flags;
+
+ return ret;
+}
+
+/**
+ * omap4_enter_idle - Programs OMAP4 to enter the specified state
+ * @dev: cpuidle device
+ * @state: The target state to be programmed
+ *
+ * Called from the CPUidle framework to program the device to the
+ * specified low power state selected by the governor.
+ * Returns the amount of time spent in the low power state.
+ */
+static int omap4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct omap4_processor_cx *cx = cpuidle_get_statedata(state);
+ struct timespec ts_preidle, ts_postidle, ts_idle;
+ u32 cpu1_state;
+ int cpu_id = smp_processor_id();
+
+ /* Used to keep track of the total time in idle */
+ getnstimeofday(&ts_preidle);
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ /*
+ * Continue to do only WFI on CPU0 till CPU1 hits OFF state.
+ * This is necessary to honour hardware recommondation
+ * of triggeing all the possible low power modes once CPU1 is
+ * out of coherency and in OFF mode.
+ * Update dev->last_state so that governor stats reflects right
+ * data.
+ */
+ cpu1_state = pwrdm_read_pwrst(cpu1_pd);
+ if ((cpu1_state != PWRDM_POWER_OFF) || (!cx->valid)) {
+ dev->last_state = dev->safe_state;
+ cx = cpuidle_get_statedata(dev->safe_state);
+ }
+
+ pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+ omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+ pwrdm_set_logic_retst(core_pd, cx->core_logic_state);
+ omap_set_pwrdm_state(core_pd, cx->core_state);
+
+ if (cx->type > OMAP4_STATE_C1)
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+
+ omap4_enter_sleep(dev->cpu, cx->cpu0_state);
+
+ /* restore the MPU and CORE states to ON */
+ omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
+ omap_set_pwrdm_state(core_pd, PWRDM_POWER_ON);
+ if (cx->type > OMAP4_STATE_C1)
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+
+ getnstimeofday(&ts_postidle);
+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
+
+ local_irq_enable();
+ local_fiq_enable();
+
+ return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC;
+}
+
+/**
+ * omap4_enter_idle_bm - Checks for any bus activity
+ * @dev: cpuidle device
+ * @state: The target state to be programmed
+ *
+ * Used for C states with CPUIDLE_FLAG_CHECK_BM flag set. This
+ * function checks for any pending activity and then programs the
+ * device to the specified or a safer state.
+ */
+static int omap4_enter_idle_bm(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ if ((omap4_idle_bm_busy())) {
+ BUG_ON(!dev->safe_state);
+ state = dev->safe_state;
+ }
+
+ dev->last_state = state;
+ return omap4_enter_idle(dev, state);
+}
+
+DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
+
+/**
+ * omap4_init_power_states - Initialises the OMAP4 specific C states.
+ *
+ * Below is the desciption of each C state.
+ * C1 : CPUx wfi + MPU inative + Core inactive
+ */
+void omap4_init_power_states(void)
+{
+ /*
+ * C1 - CPU0 WFI + CPU1 OFF + MPU ON + CORE ON
+ */
+ omap4_power_states[OMAP4_STATE_C1].valid =
+ cpuidle_params_table[OMAP4_STATE_C1].valid;
+ omap4_power_states[OMAP4_STATE_C1].type = OMAP4_STATE_C1;
+ omap4_power_states[OMAP4_STATE_C1].exit_latency=
+ cpuidle_params_table[OMAP4_STATE_C1].exit_latency;
+ omap4_power_states[OMAP4_STATE_C1].target_residency =
+ cpuidle_params_table[OMAP4_STATE_C1].target_residency;
+ omap4_power_states[OMAP4_STATE_C1].cpu0_state = PWRDM_POWER_ON;
+ omap4_power_states[OMAP4_STATE_C1].mpu_state = PWRDM_POWER_ON;
+ omap4_power_states[OMAP4_STATE_C1].mpu_logic_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C1].core_state = PWRDM_POWER_ON;
+ omap4_power_states[OMAP4_STATE_C1].core_logic_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID;
+ omap4_power_states[OMAP4_STATE_C1].desc = "MPU ON + CORE ON";
+
+ /*
+ * C2 - CPU0 INA + CPU1 OFF + MPU INA + CORE INA
+ */
+ omap4_power_states[OMAP4_STATE_C2].valid =
+ cpuidle_params_table[OMAP4_STATE_C2].valid;
+ omap4_power_states[OMAP4_STATE_C2].type = OMAP4_STATE_C2;
+ omap4_power_states[OMAP4_STATE_C2].exit_latency =
+ cpuidle_params_table[OMAP4_STATE_C2].exit_latency;
+ omap4_power_states[OMAP4_STATE_C2].target_residency =
+ cpuidle_params_table[OMAP4_STATE_C2].target_residency;
+ omap4_power_states[OMAP4_STATE_C2].cpu0_state = PWRDM_POWER_INACTIVE;
+ omap4_power_states[OMAP4_STATE_C2].mpu_state = PWRDM_POWER_INACTIVE;
+ omap4_power_states[OMAP4_STATE_C2].mpu_logic_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C2].core_state = PWRDM_POWER_INACTIVE;
+ omap4_power_states[OMAP4_STATE_C2].core_logic_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
+ omap4_power_states[OMAP4_STATE_C2].desc = "MPU INA + CORE INA";
+
+ /*
+ * C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE CSWR
+ */
+ omap4_power_states[OMAP4_STATE_C3].valid =
+ cpuidle_params_table[OMAP4_STATE_C3].valid;
+ omap4_power_states[OMAP4_STATE_C3].type = OMAP4_STATE_C3;
+ omap4_power_states[OMAP4_STATE_C3].exit_latency =
+ cpuidle_params_table[OMAP4_STATE_C3].exit_latency;
+ omap4_power_states[OMAP4_STATE_C3].target_residency =
+ cpuidle_params_table[OMAP4_STATE_C3].target_residency;
+ omap4_power_states[OMAP4_STATE_C3].cpu0_state = PWRDM_POWER_OFF;
+ omap4_power_states[OMAP4_STATE_C3].mpu_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C3].mpu_logic_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C3].core_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C3].core_logic_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID |
+ CPUIDLE_FLAG_CHECK_BM;
+ omap4_power_states[OMAP4_STATE_C3].desc = "MPU CSWR + CORE CSWR";
+
+ /*
+ * C4 - CPU0 OFF + CPU1 OFF + MPU OFF + CORE CSWR
+ */
+ omap4_power_states[OMAP4_STATE_C4].valid =
+ cpuidle_params_table[OMAP4_STATE_C4].valid;
+ omap4_power_states[OMAP4_STATE_C4].type = OMAP4_STATE_C4;
+ omap4_power_states[OMAP4_STATE_C4].exit_latency =
+ cpuidle_params_table[OMAP4_STATE_C4].exit_latency;
+ omap4_power_states[OMAP4_STATE_C4].target_residency =
+ cpuidle_params_table[OMAP4_STATE_C4].target_residency;
+ omap4_power_states[OMAP4_STATE_C4].cpu0_state = PWRDM_POWER_OFF;
+ omap4_power_states[OMAP4_STATE_C4].mpu_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C4].mpu_logic_state = PWRDM_POWER_OFF;
+ omap4_power_states[OMAP4_STATE_C4].core_state = PWRDM_POWER_RET;
+ omap4_power_states[OMAP4_STATE_C4].core_logic_state = PWRDM_POWER_OFF;
+ omap4_power_states[OMAP4_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID |
+ CPUIDLE_FLAG_CHECK_BM;
+ omap4_power_states[OMAP4_STATE_C4].desc = "MPU OSWR + CORE OSWR";
+
+}
+
+struct cpuidle_driver omap4_idle_driver = {
+ .name = "omap4_idle",
+ .owner = THIS_MODULE,
+};
+
+/*
+ * CPU hotplug notifier to update the C-states when
+ * CPU1 is offline or onine. While updating C-state flag,
+ * keep the cpuidle disabled.
+ */
+static int __cpuinit omap_cpu_hotplug_notify(struct notifier_block *self,
+ unsigned long action, void *unused)
+{
+ switch (action) {
+ case CPU_ONLINE:
+ disable_hlt();
+ needs_state_data_update = 1;
+ state_flags = CPUIDLE_FLAG_IGNORE;
+ enable_hlt();
+ break;
+ case CPU_DEAD:
+ disable_hlt();
+ needs_state_data_update = 1;
+ state_flags = CPUIDLE_FLAG_TIME_VALID;
+ enable_hlt();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata omap_ilde_hotplug_notifier = {
+ .notifier_call = omap_cpu_hotplug_notify,
+};
+
+/**
+ * omap4_idle_init - Init routine for OMAP4 idle
+ *
+ * Registers the OMAP4 specific cpuidle driver with the cpuidle
+ * framework with the valid set of states.
+ */
+int __init omap4_idle_init(void)
+{
+ int cpu_id = 0, i, count = 0, ret;
+ struct omap4_processor_cx *cx;
+ struct cpuidle_state *state;
+ struct cpuidle_device *dev;
+
+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
+ cpu1_pd = pwrdm_lookup("cpu1_pwrdm");
+ core_pd = pwrdm_lookup("core_pwrdm");
+
+ omap4_init_power_states();
+ cpuidle_register_driver(&omap4_idle_driver);
+
+ dev = &per_cpu(omap4_idle_dev, cpu_id);
+ dev->cpu = cpu_id;
+ count = 0;
+ for (i = OMAP4_STATE_C1; i < OMAP4_MAX_STATES; i++) {
+ cx = &omap4_power_states[i];
+ state = &dev->states[count];
+
+ if (!cx->valid)
+ continue;
+ cpuidle_set_statedata(state, cx);
+ state->exit_latency = cx->exit_latency;
+ state->target_residency = cx->target_residency;
+ state->flags = cx->flags;
+ if (cx->type == OMAP4_STATE_C1)
+ dev->safe_state = state;
+ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
+ omap4_enter_idle_bm : omap4_enter_idle;
+
+ sprintf(state->name, "C%d", count+1);
+ strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
+ count++;
+ }
+
+ if (!count)
+ return -EINVAL;
+ dev->state_count = count;
+ dev->prepare = omap4_prepare_idle;
+
+ if (cpuidle_register_device(dev)) {
+ pr_err("%s: CPUidle register device failed\n", __func__);
+ return -EIO;
+ }
+
+ ret = register_hotcpu_notifier(&omap_ilde_hotplug_notifier);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+#else
+int __init omap4_idle_init(void)
+{
+ return 0;
+}
+#endif /* CONFIG_CPU_IDLE */
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 5b8ca68..d2b7058 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -29,6 +29,7 @@
#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/dma.h>
+#include <plat/gpu.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
#include <plat/omap4-keypad.h>
@@ -292,6 +293,21 @@ static inline void omap_init_mbox(void) { }
static inline void omap_init_sti(void) {}
+#if defined CONFIG_ARCH_OMAP4
+
+static struct platform_device omap_abe_dai = {
+ .name = "omap-abe-dai",
+ .id = -1,
+};
+
+static inline void omap_init_abe(void)
+{
+ platform_device_register(&omap_abe_dai);
+}
+#else
+static inline void omap_init_abe(void) {}
+#endif
+
#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
static struct platform_device omap_pcm = {
@@ -673,6 +689,63 @@ static void omap_init_vout(void)
static inline void omap_init_vout(void) {}
#endif
+static struct omap_device_pm_latency omap_gpu_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static struct platform_device omap_omaplfb_device = {
+ .name = "omaplfb",
+ .id = -1,
+};
+
+
+static void omap_init_gpu(void)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ int max_omap_gpu_hwmod_name_len = 16;
+ char oh_name[max_omap_gpu_hwmod_name_len];
+ int l;
+ struct gpu_platform_data *pdata;
+ char *name = "pvrsrvkm";
+
+ l = snprintf(oh_name, max_omap_gpu_hwmod_name_len,
+ "gpu");
+ WARN(l >= max_omap_gpu_hwmod_name_len,
+ "String buffer overflow in GPU device setup\n");
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+
+ pr_err("omap_init_gpu: Could not look up %s\n", oh_name);
+ return;
+ }
+
+ pdata = kzalloc(sizeof(struct gpu_platform_data),
+ GFP_KERNEL);
+ if (!pdata) {
+ pr_err("omap_init_gpu: Platform data memory allocation failed\n");
+ return;
+ }
+
+ pdata->device_enable = omap_device_enable;
+ pdata->device_idle = omap_device_idle;
+ pdata->device_shutdown = omap_device_shutdown;
+
+ od = omap_device_build(name, 0, oh, pdata,
+ sizeof(struct gpu_platform_data),
+ omap_gpu_latency, ARRAY_SIZE(omap_gpu_latency), 0);
+ WARN(IS_ERR(od), "Could not build omap_device for %s %s\n",
+ name, oh_name);
+
+ kfree(pdata);
+ platform_device_register(&omap_omaplfb_device);
+}
+
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
@@ -681,6 +754,7 @@ static int __init omap2_init_devices(void)
* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
+ omap_init_abe();
omap_init_audio();
omap_init_camera();
omap_init_mbox();
@@ -691,6 +765,7 @@ static int __init omap2_init_devices(void)
omap_init_sham();
omap_init_aes();
omap_init_vout();
+ omap_init_gpu();
return 0;
}
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 543fcb8..a5b7a23 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -25,6 +25,7 @@
#include <video/omapdss.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
static struct platform_device omap_display_device = {
.name = "omapdss",
@@ -42,20 +43,6 @@ static struct omap_device_pm_latency omap_dss_latency[] = {
},
};
-/* oh_core is used for getting opt-clocks */
-static struct omap_hwmod *oh_core;
-
-static bool opt_clock_available(const char *clk_role)
-{
- int i;
-
- for (i = 0; i < oh_core->opt_clks_cnt; i++) {
- if (!strcmp(oh_core->opt_clks[i].role, clk_role))
- return true;
- }
- return false;
-}
-
struct omap_dss_hwmod_data {
const char *oh_name;
const char *dev_name;
@@ -109,16 +96,9 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
}
- /* opt_clks are always associated with dss hwmod */
- oh_core = omap_hwmod_lookup("dss_core");
- if (!oh_core) {
- pr_err("Could not look up dss_core.\n");
- return -ENODEV;
- }
-
pdata.board_data = board_data;
- pdata.board_data->get_last_off_on_transaction_id = NULL;
- pdata.opt_clock_available = opt_clock_available;
+ pdata.board_data->get_context_loss_count =
+ omap_pm_get_dev_context_loss_count;
for (i = 0; i < oh_count; i++) {
oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 4e4da61..aa6e517 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -19,8 +19,13 @@
#include <plat/clock.h>
#include "clock.h"
+#include "cm1_44xx.h"
#include "cm-regbits-44xx.h"
+#define OMAP_1GHz 1000000000
+#define OMAP_920MHz 920000000
+#define OMAP_748MHz 748000000
+
/* Supported only on OMAP4 */
int omap4_dpllmx_gatectrl_read(struct clk *clk)
{
@@ -82,3 +87,110 @@ const struct clkops clkops_omap4_dpllmx_ops = {
.deny_idle = omap4_dpllmx_deny_gatectrl,
};
+int omap4460_mpu_dpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct dpll_data *dd;
+ u32 v;
+ unsigned long dpll_rate;
+
+ if (!clk || !rate || !clk->parent)
+ return -EINVAL;
+
+ dd = clk->parent->dpll_data;
+
+ if (!dd)
+ return -EINVAL;
+
+ if (!clk->parent->set_rate)
+ return -EINVAL;
+
+ /*
+ * On OMAP4460, to obtain MPU DPLL frequency higher
+ * than 1GHz, DCC (Duty Cycle Correction) needs to
+ * be enabled.
+ * And needs to be kept disabled for < 1 Ghz.
+ */
+ dpll_rate = omap2_get_dpll_rate(clk->parent);
+ v = __raw_readl(dd->mult_div1_reg);
+ if (rate < OMAP_1GHz) {
+ if (rate == dpll_rate)
+ return 0;
+ /* If DCC is enabled, disable it */
+ if (v & OMAP4460_DCC_EN_MASK) {
+ v &= ~OMAP4460_DCC_EN_MASK;
+ __raw_writel(v, dd->mult_div1_reg);
+ }
+ clk->parent->set_rate(clk->parent, rate);
+ } else {
+ if (rate == dpll_rate/2)
+ return 0;
+ v &= ~OMAP4460_DCC_COUNT_MAX_MASK;
+ v |= (5 << OMAP4460_DCC_COUNT_MAX_SHIFT);
+ v |= OMAP4460_DCC_EN_MASK;
+ __raw_writel(v, dd->mult_div1_reg);
+ /*
+ * On 4460, the MPU clk for frequencies higher than 1Ghz
+ * is sourced from CLKOUTX2_M3, instead of CLKOUT_M2, while
+ * value of M3 is fixed to 1. Hence for frequencies higher
+ * than 1 Ghz, lock the DPLL at half the rate so the
+ * CLKOUTX2_M3 then matches the requested rate.
+ */
+ clk->parent->set_rate(clk->parent, rate/2);
+ }
+
+ clk->rate = rate;
+
+ /*
+ * The interconnect frequency to EMIF should
+ * be switched between MPU clk divide by 4 (for
+ * frequencies higher than 920Mhz) and MPU clk divide
+ * by 2 (for frequencies lower than or equal to 920Mhz)
+ * Also the async bridge to ABE must be MPU clk divide
+ * by 8 for MPU clk > 748Mhz and MPU clk divide by 4
+ * for lower frequencies.
+ */
+ v = __raw_readl(OMAP4430_CM_MPU_MPU_CLKCTRL);
+ if (rate > OMAP_920MHz)
+ v |= OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK;
+ else
+ v &= ~OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK;
+
+ if (rate > OMAP_748MHz)
+ v |= OMAP4460_CLKSEL_ABE_DIV_MODE_MASK;
+ else
+ v &= ~OMAP4460_CLKSEL_ABE_DIV_MODE_MASK;
+ __raw_writel(v, OMAP4430_CM_MPU_MPU_CLKCTRL);
+
+ return 0;
+}
+
+long omap4460_mpu_dpll_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk || !rate || !clk->parent)
+ return -EINVAL;
+
+ if (clk->parent->round_rate)
+ return clk->parent->round_rate(clk, rate);
+ else
+ return 0;
+}
+
+unsigned long omap4460_mpu_dpll_recalc(struct clk *clk)
+{
+ struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->parent)
+ return -EINVAL;
+
+ dd = clk->parent->dpll_data;
+
+ if (!dd)
+ return -EINVAL;
+
+ v = __raw_readl(dd->mult_div1_reg);
+ if (v & OMAP4460_DCC_EN_MASK)
+ return omap2_get_dpll_rate(clk->parent) * 2;
+ else
+ return omap2_get_dpll_rate(clk->parent);
+}
diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c
new file mode 100644
index 0000000..8c82f2c
--- /dev/null
+++ b/arch/arm/mach-omap2/dvfs.c
@@ -0,0 +1,988 @@
+/*
+ * OMAP3/OMAP4 DVFS Management Routines
+ *
+ * Author: Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Vishwanath BS <vishwanath.bs@ti.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/err.h>
+#include <linux/spinlock.h>
+#include <linux/plist.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <plat/common.h>
+#include <plat/omap_device.h>
+#include <plat/omap_hwmod.h>
+#include <plat/clock.h>
+#include "dvfs.h"
+#include "smartreflex.h"
+#include "powerdomain.h"
+
+/**
+ * DOC: Introduction
+ * =================
+ * DVFS is a technique that uses the optimal operating frequency and voltage to
+ * allow a task to be performed in the required amount of time.
+ * OMAP processors have voltage domains whose voltage can be scaled to
+ * various levels depending on which the operating frequencies of certain
+ * devices belonging to the domain will also need to be scaled. This voltage
+ * frequency tuple is known as Operating Performance Point (OPP). A device
+ * can have multiple OPP's. Also a voltage domain could be shared between
+ * multiple devices. Also there could be dependencies between various
+ * voltage domains for maintaining system performance like VDD<X>
+ * should be at voltage v1 when VDD<Y> is at voltage v2.
+ *
+ * The design of this framework takes into account all the above mentioned
+ * points. To summarize the basic design of DVFS framework:-
+ *
+ * 1. Have device opp tables for each device whose operating frequency can be
+ * scaled. This is easy now due to the existance of hwmod layer which
+ * allow storing of device specific info. The device opp tables contain
+ * the opp pairs (frequency voltage tuples), the voltage domain pointer
+ * to which the device belongs to, the device specific set_rate and
+ * get_rate API's which will do the actual scaling of the device frequency
+ * and retrieve the current device frequency.
+ * 2. Introduce use counting on a per VDD basis. This is to take care multiple
+ * requests to scale a VDD. The VDD will be scaled to the maximum of the
+ * voltages requested.
+ * 3. Keep track of all scalable devices belonging to a particular voltage
+ * domain the voltage layer.
+ * 4. Keep track of frequency requests for each of the device. This will enable
+ * to scale individual devices to different frequency (even w/o scaling
+ * voltage aka frequency throttling)
+ * 5. Generic dvfs API that can be called by anybody to scale a device opp.
+ * This API takes the device pointer and frequency to which the device
+ * needs to be scaled to. This API then internally finds out the voltage
+ * domain to which the device belongs to and the voltage to which the voltage
+ * domain needs to be put to for the device to be scaled to the new frequency
+ * from he device opp table. Then this API will add requested frequency into
+ * the corresponding target device frequency list and add voltage request to
+ * the corresponding vdd. Subsequently it calls voltage scale function which
+ * will find out the highest requested voltage for the given vdd and scales
+ * the voltage to the required one. It also runs through the list of all
+ * scalable devices belonging to this voltage domain and scale them to the
+ * appropriate frequencies using the set_rate pointer in the device opp
+ * tables.
+ * 6. Handle inter VDD dependecies.
+ *
+ *
+ * DOC: The Core DVFS data structure:
+ * ==================================
+ * Structure Name Example Tree
+ * ---------
+ * /|\ +-------------------+ +-------------------+
+ * | |User2 (dev2, freq2)+---\ |User4 (dev4, freq4)+---\
+ * | +-------------------+ | +-------------------+ |
+ * (struct omap_dev_user_list) | |
+ * | +-------------------+ | +-------------------+ |
+ * | |User1 (dev1, freq1)+---| |User3 (dev3, freq3)+---|
+ * \|/ +-------------------+ | +-------------------+ |
+ * --------- | |
+ * /|\ +------------+------+ +---------------+--+
+ * | | DEV1 (dev, | | DEV2 (dev) |
+ * (struct omap_vdd_dev_list)|omap_dev_user_list)| |omap_dev_user_list|
+ * | +------------+------+ +--+---------------+
+ * \|/ /|\ /-----+-------------+------> others..
+ * --------- Frequency |
+ * /|\ +--+------------------+
+ * | | VDD_n |
+ * | | (omap_vdd_dev_list, |
+ * (struct omap_vdd_dvfs_info)** | omap_vdd_user_list) |
+ * | +--+------------------+
+ * | | (ROOT NODE: omap_dvfs_info_list)
+ * \|/ |
+ * --------- Voltage \---+-------------+----------> others..
+ * /|\ \|/ +-------+----+ +-----+--------+
+ * | | vdd_user2 | | vdd_user3 |
+ * (struct omap_vdd_user_list) | (dev, volt)| | (dev, volt) |
+ * \|/ +------------+ +--------------+
+ * ---------
+ * Key: ** -> Root of the tree.
+ * NOTE: we use the priority to store the voltage/frequency
+ *
+ * For voltage dependency description, see: struct dependency:
+ * voltagedomain -> (description of the voltagedomain)
+ * omap_vdd_info -> (vdd information)
+ * omap_vdd_dep_info[]-> (stores array of depedency info)
+ * omap_vdd_dep_volt[] -> (stores array of maps)
+ * (main_volt -> dep_volt) (a singular map)
+ */
+
+/* Macros to give idea about scaling directions */
+#define DVFS_VOLT_SCALE_DOWN 0
+#define DVFS_VOLT_SCALE_NONE 1
+#define DVFS_VOLT_SCALE_UP 2
+
+/**
+ * struct omap_dev_user_list - Structure maitain userlist per devide
+ * @dev: The device requesting for a particular frequency
+ * @node: The list head entry
+ *
+ * Using this structure, user list (requesting dev * and frequency) for
+ * each device is maintained. This is how we can have different devices
+ * at different frequencies (to support frequency locking and throttling).
+ * Even if one of the devices in a given vdd has locked it's frequency,
+ * other's can still scale their frequency using this list.
+ * If no one has placed a frequency request for a device, then device is
+ * set to the frequency from it's opp table.
+ */
+struct omap_dev_user_list {
+ struct device *dev;
+ struct plist_node node;
+};
+
+/**
+ * struct omap_vdd_dev_list - Device list per vdd
+ * @dev: The device belonging to a particular vdd
+ * @node: The list head entry
+ * @freq_user_list: The list of users for vdd device
+ * @clk: frequency control clock for this dev
+ * @user_lock: The lock for plist manipulation
+ */
+struct omap_vdd_dev_list {
+ struct device *dev;
+ struct list_head node;
+ struct plist_head freq_user_list;
+ struct clk *clk;
+ spinlock_t user_lock; /* spinlock for plist */
+};
+
+/**
+ * struct omap_vdd_user_list - The per vdd user list
+ * @dev: The device asking for the vdd to be set at a particular
+ * voltage
+ * @node: The list head entry
+ */
+struct omap_vdd_user_list {
+ struct device *dev;
+ struct plist_node node;
+};
+
+/**
+ * struct omap_vdd_dvfs_info - The per vdd dvfs info
+ * @node: list node for vdd_dvfs_info list
+ * @user_lock: spinlock for plist operations
+ * @vdd_user_list: The vdd user list
+ * @voltdm: Voltage domains for which dvfs info stored
+ * @dev_list: Device list maintained per domain
+ *
+ * This is a fundamental structure used to store all the required
+ * DVFS related information for a vdd.
+ */
+struct omap_vdd_dvfs_info {
+ struct list_head node;
+
+ spinlock_t user_lock; /* spin lock */
+ struct plist_head vdd_user_list;
+ struct voltagedomain *voltdm;
+ struct list_head dev_list;
+};
+
+static LIST_HEAD(omap_dvfs_info_list);
+static DEFINE_MUTEX(omap_dvfs_lock);
+
+/* Dvfs scale helper function */
+static int _dvfs_scale(struct device *req_dev, struct device *target_dev,
+ struct omap_vdd_dvfs_info *tdvfs_info);
+
+/* Few search functions to traverse and find pointers of interest */
+
+/**
+ * _dvfs_info_to_dev() - Locate the parent device associated to dvfs_info
+ * @dvfs_info: dvfs_info to search for
+ *
+ * Returns NULL on failure.
+ */
+static struct device *_dvfs_info_to_dev(struct omap_vdd_dvfs_info *dvfs_info)
+{
+ struct omap_vdd_dev_list *tmp_dev;
+ if (IS_ERR_OR_NULL(dvfs_info))
+ return NULL;
+ if (list_empty(&dvfs_info->dev_list))
+ return NULL;
+ tmp_dev = list_first_entry(&dvfs_info->dev_list,
+ struct omap_vdd_dev_list, node);
+ return tmp_dev->dev;
+}
+
+/**
+ * _dev_to_dvfs_info() - Locate the dvfs_info for a device
+ * @dev: dev to search for
+ *
+ * Returns NULL on failure.
+ */
+static struct omap_vdd_dvfs_info *_dev_to_dvfs_info(struct device *dev)
+{
+ struct omap_vdd_dvfs_info *dvfs_info;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (IS_ERR_OR_NULL(dev))
+ return NULL;
+
+ list_for_each_entry(dvfs_info, &omap_dvfs_info_list, node) {
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == dev)
+ return dvfs_info;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * _voltdm_to_dvfs_info() - Locate a dvfs_info given a voltdm pointer
+ * @voltdm: voltdm to search for
+ *
+ * Returns NULL on failure.
+ */
+static
+struct omap_vdd_dvfs_info *_voltdm_to_dvfs_info(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_dvfs_info *dvfs_info;
+
+ if (IS_ERR_OR_NULL(voltdm))
+ return NULL;
+
+ list_for_each_entry(dvfs_info, &omap_dvfs_info_list, node) {
+ if (dvfs_info->voltdm == voltdm)
+ return dvfs_info;
+ }
+
+ return NULL;
+}
+
+/**
+ * _volt_to_opp() - Find OPP corresponding to a given voltage
+ * @dev: device pointer associated with the OPP list
+ * @volt: voltage to search for in uV
+ *
+ * Searches for exact match in the OPP list and returns handle to the matching
+ * OPP if found, else returns ERR_PTR in case of error and should be handled
+ * using IS_ERR. If there are multiple opps with same voltage, it will return
+ * the first available entry. Return pointer should be checked against IS_ERR.
+ *
+ * NOTE: since this uses OPP functions, use under rcu_lock. This function also
+ * assumes that the cpufreq table and OPP table are in sync - any modifications
+ * to either should be synchronized.
+ */
+static struct opp *_volt_to_opp(struct device *dev, unsigned long volt)
+{
+ struct opp *opp = ERR_PTR(-ENODEV);
+ unsigned long f = 0;
+
+ do {
+ opp = opp_find_freq_ceil(dev, &f);
+ if (IS_ERR(opp))
+ break;
+ if (opp_get_voltage(opp) >= volt)
+ break;
+ f++;
+ } while (1);
+
+ return opp;
+}
+
+/* rest of the helper functions */
+/**
+ * _add_vdd_user() - Add a voltage request
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @dev: device making the request
+ * @volt: requested voltage in uV
+ *
+ * Adds the given device's voltage request into corresponding
+ * vdd's omap_vdd_dvfs_info user list (plist). This list is used
+ * to find the maximum voltage request for a given vdd.
+ *
+ * Returns 0 on success.
+ */
+static int _add_vdd_user(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *dev, unsigned long volt)
+{
+ struct omap_vdd_user_list *user = NULL, *temp_user;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_warn(dev, "%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ spin_lock(&dvfs_info->user_lock);
+ plist_for_each_entry(temp_user, &dvfs_info->vdd_user_list, node) {
+ if (temp_user->dev == dev) {
+ user = temp_user;
+ break;
+ }
+ }
+
+ if (!user) {
+ user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_ATOMIC);
+ if (!user) {
+ dev_err(dev,
+ "%s: Unable to creat a new user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ spin_unlock(&dvfs_info->user_lock);
+ return -ENOMEM;
+ }
+ user->dev = dev;
+ } else {
+ plist_del(&user->node, &dvfs_info->vdd_user_list);
+ }
+
+ plist_node_init(&user->node, volt);
+ plist_add(&user->node, &dvfs_info->vdd_user_list);
+
+ spin_unlock(&dvfs_info->user_lock);
+ return 0;
+}
+
+/**
+ * _remove_vdd_user() - Remove a voltage request
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @dev: device making the request
+ *
+ * Removes the given device's voltage request from corresponding
+ * vdd's omap_vdd_dvfs_info user list (plist).
+ *
+ * Returns 0 on success.
+ */
+static int _remove_vdd_user(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *dev)
+{
+ struct omap_vdd_user_list *user = NULL, *temp_user;
+ int ret = 0;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_err(dev, "%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ spin_lock(&dvfs_info->user_lock);
+ plist_for_each_entry(temp_user, &dvfs_info->vdd_user_list, node) {
+ if (temp_user->dev == dev) {
+ user = temp_user;
+ break;
+ }
+ }
+
+ if (user)
+ plist_del(&user->node, &dvfs_info->vdd_user_list);
+ else {
+ dev_err(dev, "%s: Unable to find the user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ ret = -ENOENT;
+ }
+
+ spin_unlock(&dvfs_info->user_lock);
+ kfree(user);
+
+ return ret;
+}
+
+/**
+ * _add_freq_request() - Add a requested device frequency
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @req_dev: device making the request
+ * @target_dev: target device for which frequency request is being made
+ * @freq: target device frequency
+ *
+ * This adds a requested frequency into target device's frequency list.
+ *
+ * Returns 0 on success.
+ */
+static int _add_freq_request(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *req_dev, struct device *target_dev, unsigned long freq)
+{
+ struct omap_dev_user_list *dev_user = NULL, *tmp_user;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_warn(target_dev, "%s: VDD specified does not exist!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == target_dev)
+ break;
+ }
+
+ if (temp_dev->dev != target_dev) {
+ dev_warn(target_dev, "%s: target_dev does not exist!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ spin_lock(&temp_dev->user_lock);
+ plist_for_each_entry(tmp_user, &temp_dev->freq_user_list, node) {
+ if (tmp_user->dev == req_dev) {
+ dev_user = tmp_user;
+ break;
+ }
+ }
+
+ if (!dev_user) {
+ dev_user = kzalloc(sizeof(struct omap_dev_user_list),
+ GFP_ATOMIC);
+ if (!dev_user) {
+ dev_err(target_dev,
+ "%s: Unable to creat a new user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ spin_unlock(&temp_dev->user_lock);
+ return -ENOMEM;
+ }
+ dev_user->dev = req_dev;
+ } else {
+ plist_del(&dev_user->node, &temp_dev->freq_user_list);
+ }
+
+ plist_node_init(&dev_user->node, freq);
+ plist_add(&dev_user->node, &temp_dev->freq_user_list);
+ spin_unlock(&temp_dev->user_lock);
+ return 0;
+}
+
+/**
+ * _remove_freq_request() - Remove the requested device frequency
+ *
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @req_dev: device removing the request
+ * @target_dev: target device from which frequency request is being removed
+ *
+ * This removes a requested frequency from target device's frequency list.
+ *
+ * Returns 0 on success.
+ */
+static int _remove_freq_request(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *req_dev, struct device *target_dev)
+{
+ struct omap_dev_user_list *dev_user = NULL, *tmp_user;
+ int ret = 0;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_warn(target_dev, "%s: VDD specified does not exist!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == target_dev)
+ break;
+ }
+
+ if (temp_dev->dev != target_dev) {
+ dev_warn(target_dev, "%s: target_dev does not exist!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ spin_lock(&temp_dev->user_lock);
+ plist_for_each_entry(tmp_user, &temp_dev->freq_user_list, node) {
+ if (tmp_user->dev == req_dev) {
+ dev_user = tmp_user;
+ break;
+ }
+ }
+
+ if (dev_user) {
+ plist_del(&dev_user->node, &temp_dev->freq_user_list);
+ } else {
+ dev_err(target_dev,
+ "%s: Unable to remove the user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ ret = -EINVAL;
+ }
+
+ spin_unlock(&temp_dev->user_lock);
+ kfree(dev_user);
+
+ return ret;
+}
+
+/**
+ * _dep_scan_table() - Scan a dependency table and mark for scaling
+ * @dev: device requesting the dependency scan (req_dev)
+ * @dep_info: dependency information (contains the table)
+ * @main_volt: voltage dependency to search for
+ *
+ * This runs down the table provided to find the match for main_volt
+ * provided and sets up a scale request for the dependent domain
+ * for the dependent voltage.
+ *
+ * Returns 0 if all went well.
+ */
+static int _dep_scan_table(struct device *dev,
+ struct omap_vdd_dep_info *dep_info, unsigned long main_volt)
+{
+ struct omap_vdd_dep_volt *dep_table = dep_info->dep_table;
+ int i;
+ unsigned long dep_volt = 0;
+
+ if (!dep_table) {
+ dev_err(dev, "%s: deptable not present for vdd%s\n",
+ __func__, dep_info->name);
+ return -EINVAL;
+ }
+
+ /* Now scan through the the dep table for a match */
+ for (i = 0; i < dep_info->nr_dep_entries; i++) {
+ if (dep_table[i].main_vdd_volt == main_volt) {
+ dep_volt = dep_table[i].dep_vdd_volt;
+ break;
+ }
+ }
+ if (!dep_volt) {
+ dev_warn(dev, "%s: %ld volt map missing in vdd_%s\n",
+ __func__, main_volt, dep_info->name);
+ return -EINVAL;
+ }
+
+ /* populate voltdm if it is not present */
+ if (!dep_info->_dep_voltdm) {
+ dep_info->_dep_voltdm = voltdm_lookup(dep_info->name);
+ if (!dep_info->_dep_voltdm) {
+ dev_warn(dev, "%s: unable to get vdm%s\n",
+ __func__, dep_info->name);
+ return -ENODEV;
+ }
+ }
+
+ /* See if dep_volt is possible for the vdd*/
+ i = _add_vdd_user(_voltdm_to_dvfs_info(dep_info->_dep_voltdm),
+ dev, dep_volt);
+ if (i)
+ dev_err(dev, "%s: Failed to add dep to domain %s volt=%ld\n",
+ __func__, dep_info->name, dep_volt);
+ return i;
+}
+
+/**
+ * _dep_scan_domains() - Scan dependency domains for a device
+ * @dev: device requesting the scan
+ * @vdd: vdd_info corresponding to the device
+ * @main_volt: voltage to scan for
+ *
+ * Since each domain *may* have multiple dependent domains, we scan
+ * through each of the dependent domains and invoke _dep_scan_table to
+ * scan each table for dependent domain for dependency scaling.
+ *
+ * This assumes that the dependent domain information is NULL entry terminated.
+ * Returns 0 if all went well.
+ */
+static int _dep_scan_domains(struct device *dev,
+ struct omap_vdd_info *vdd, unsigned long main_volt)
+{
+ struct omap_vdd_dep_info *dep_info = vdd->dep_vdd_info;
+ int ret = 0, r;
+
+ if (!dep_info) {
+ dev_dbg(dev, "%s: No dependent VDD\n", __func__);
+ return 0;
+ }
+
+ /* First scan through the mydomain->dep_domain list */
+ while (dep_info->nr_dep_entries) {
+ r = _dep_scan_table(dev, dep_info, main_volt);
+ /* Store last failed value */
+ ret = (r) ? r : ret;
+ dep_info++;
+ }
+
+ return ret;
+}
+
+/**
+ * _dep_scale_domains() - Cause a scale of all dependent domains
+ * @req_dev: device requesting the scale
+ * @req_vdd: vdd_info corresponding to the requesting device.
+ *
+ * This walks through every dependent domain and triggers a scale
+ * It is assumed that the corresponding scale handling for the
+ * domain translates this to freq and voltage scale operations as
+ * needed.
+ *
+ * Note: This is uses _dvfs_scale and one should be careful not to
+ * create a circular depedency (e.g. vdd_mpu->vdd_core->vdd->mpu)
+ * which can create deadlocks. No protection is provided to prevent
+ * this condition and a tree organization is assumed.
+ *
+ * Returns 0 if all went fine.
+ */
+static int _dep_scale_domains(struct device *req_dev,
+ struct omap_vdd_info *req_vdd)
+{
+ struct omap_vdd_dep_info *dep_info = req_vdd->dep_vdd_info;
+ int ret = 0, r;
+
+ if (!dep_info) {
+ dev_dbg(req_dev, "%s: No dependent VDD\n", __func__);
+ return 0;
+ }
+
+ /* First scan through the mydomain->dep_domain list */
+ while (dep_info->nr_dep_entries) {
+ struct voltagedomain *tvoltdm = dep_info->_dep_voltdm;
+
+ r = 0;
+ /* Scale it only if I have a voltdm mapped up for the dep */
+ if (tvoltdm) {
+ struct omap_vdd_dvfs_info *tdvfs_info;
+ struct device *target_dev;
+ tdvfs_info = _voltdm_to_dvfs_info(tvoltdm);
+ if (!tdvfs_info) {
+ dev_warn(req_dev, "%s: no dvfs_info\n",
+ __func__);
+ goto next;
+ }
+ target_dev = _dvfs_info_to_dev(tdvfs_info);
+ if (!target_dev) {
+ dev_warn(req_dev, "%s: no target_dev\n",
+ __func__);
+ goto next;
+ }
+ r = _dvfs_scale(req_dev, target_dev, tdvfs_info);
+next:
+ if (r)
+ dev_err(req_dev, "%s: dvfs_scale to %s =%d\n",
+ __func__, dev_name(target_dev), r);
+ }
+ /* Store last failed value */
+ ret = (r) ? r : ret;
+ dep_info++;
+ }
+
+ return ret;
+}
+
+/**
+ * _dvfs_scale() : Scale the devices associated with a voltage domain
+ * @req_dev: Device requesting the scale
+ * @target_dev: Device requesting to be scaled
+ * @tdvfs_info: omap_vdd_dvfs_info pointer for the target domain
+ *
+ * This runs through the list of devices associated with the
+ * voltage domain and scales the device rates to the one requested
+ * by the user or those corresponding to the new voltage of the
+ * voltage domain. Target voltage is the highest voltage in the vdd_user_list.
+ *
+ * Returns 0 on success else the error value.
+ */
+static int _dvfs_scale(struct device *req_dev, struct device *target_dev,
+ struct omap_vdd_dvfs_info *tdvfs_info)
+{
+ unsigned long curr_volt, new_volt;
+ int volt_scale_dir = DVFS_VOLT_SCALE_DOWN;
+ struct omap_vdd_dev_list *temp_dev;
+ struct plist_node *node;
+ int ret = 0;
+ struct voltagedomain *voltdm;
+ struct omap_vdd_info *vdd;
+
+ voltdm = tdvfs_info->voltdm;
+ if (IS_ERR_OR_NULL(voltdm)) {
+ dev_err(target_dev, "%s: bad voltdm\n", __func__);
+ return -EINVAL;
+ }
+ vdd = voltdm->vdd;
+
+ /* Find the highest voltage being requested */
+ node = plist_last(&tdvfs_info->vdd_user_list);
+ new_volt = node->prio;
+
+ curr_volt = omap_vp_get_curr_volt(voltdm);
+ if (!curr_volt)
+ curr_volt = omap_voltage_get_nom_volt(voltdm);
+
+ /* Disable smartreflex module across voltage and frequency scaling */
+ omap_sr_disable(voltdm);
+
+ if (curr_volt == new_volt) {
+ volt_scale_dir = DVFS_VOLT_SCALE_NONE;
+ } else if (curr_volt < new_volt) {
+ ret = voltdm_scale(voltdm, new_volt);
+ if (ret) {
+ dev_err(target_dev,
+ "%s: Unable to scale the %s to %ld volt\n",
+ __func__, voltdm->name, new_volt);
+ goto out;
+ }
+ volt_scale_dir = DVFS_VOLT_SCALE_UP;
+ }
+
+ /* if we fail scale for dependent domains, go back to prev state */
+ ret = _dep_scan_domains(target_dev, vdd, new_volt);
+ if (ret) {
+ dev_err(target_dev,
+ "%s: Error in scan domains for vdd_%s\n",
+ __func__, voltdm->name);
+ goto fail;
+ }
+
+ /* unless we are moving down, scale dependents before we shift freq */
+ if (!(DVFS_VOLT_SCALE_DOWN == volt_scale_dir)) {
+ ret = _dep_scale_domains(target_dev, vdd);
+ if (ret) {
+ dev_err(target_dev,
+ "%s: Error(%d)scale dependent with %ld volt\n",
+ __func__, ret, new_volt);
+ goto fail;
+ }
+ }
+
+ /* Move all devices in list to the required frequencies */
+ list_for_each_entry(temp_dev, &tdvfs_info->dev_list, node) {
+ struct device *dev;
+ struct opp *opp;
+ unsigned long freq = 0;
+ int r;
+
+ dev = temp_dev->dev;
+ if (!plist_head_empty(&temp_dev->freq_user_list)) {
+ node = plist_last(&temp_dev->freq_user_list);
+ freq = node->prio;
+ } else {
+ /* dep domain? we'd probably have a voltage request */
+ rcu_read_lock();
+ opp = _volt_to_opp(dev, new_volt);
+ if (!IS_ERR(opp))
+ freq = opp_get_freq(opp);
+ rcu_read_unlock();
+ if (!freq)
+ continue;
+ }
+
+ if (freq == clk_get_rate(temp_dev->clk)) {
+ dev_dbg(dev, "%s: Already at the requested"
+ "rate %ld\n", __func__, freq);
+ continue;
+ }
+
+ r = clk_set_rate(temp_dev->clk, freq);
+ if (r < 0) {
+ dev_err(dev, "%s: clk set rate frq=%ld failed(%d)\n",
+ __func__, freq, r);
+ ret = r;
+ }
+ }
+
+ if (ret)
+ goto fail;
+
+ if (DVFS_VOLT_SCALE_DOWN == volt_scale_dir) {
+ voltdm_scale(voltdm, new_volt);
+ _dep_scale_domains(target_dev, vdd);
+ }
+
+ /* All clear.. go out gracefully */
+ goto out;
+
+fail:
+ pr_warning("%s: domain%s: No clean recovery available! could be bad!\n",
+ __func__, voltdm->name);
+out:
+ /* Re-enable Smartreflex module */
+ omap_sr_enable(voltdm);
+
+ return ret;
+}
+
+/* Public functions */
+
+/**
+ * omap_device_scale() - Set a new rate at which the device is to operate
+ * @req_dev: pointer to the device requesting the scaling.
+ * @target_dev: pointer to the device that is to be scaled
+ * @rate: the rnew rate for the device.
+ *
+ * This API gets the device opp table associated with this device and
+ * tries putting the device to the requested rate and the voltage domain
+ * associated with the device to the voltage corresponding to the
+ * requested rate. Since multiple devices can be assocciated with a
+ * voltage domain this API finds out the possible voltage the
+ * voltage domain can enter and then decides on the final device
+ * rate.
+ *
+ * Return 0 on success else the error value
+ */
+int omap_device_scale(struct device *req_dev, struct device *target_dev,
+ unsigned long rate)
+{
+ struct opp *opp;
+ unsigned long volt, freq = rate;
+ struct omap_vdd_dvfs_info *tdvfs_info;
+ struct platform_device *pdev;
+ struct omap_device *od;
+ int ret = 0;
+
+ pdev = container_of(target_dev, struct platform_device, dev);
+ if (IS_ERR_OR_NULL(pdev)) {
+ pr_err("%s: pdev is null!\n", __func__);
+ return -EINVAL;
+ }
+
+ od = container_of(pdev, struct omap_device, pdev);
+ if (IS_ERR_OR_NULL(od)) {
+ pr_err("%s: od is null!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Lock me to ensure cross domain scaling is secure */
+ mutex_lock(&omap_dvfs_lock);
+
+ rcu_read_lock();
+ opp = opp_find_freq_ceil(target_dev, &freq);
+ if (IS_ERR(opp)) {
+ rcu_read_unlock();
+ dev_err(target_dev, "%s: Unable to find OPP for freq%ld\n",
+ __func__, rate);
+ ret = -ENODEV;
+ goto out;
+ }
+ volt = opp_get_voltage(opp);
+ rcu_read_unlock();
+
+ tdvfs_info = _dev_to_dvfs_info(target_dev);
+ if (IS_ERR_OR_NULL(tdvfs_info)) {
+ dev_err(target_dev, "%s: (req=%s) no vdd![f=%ld, v=%ld]\n",
+ __func__, dev_name(req_dev), freq, volt);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = _add_freq_request(tdvfs_info, req_dev, target_dev, freq);
+ if (ret) {
+ dev_err(target_dev, "%s: freqadd(%s) failed %d[f=%ld, v=%ld]\n",
+ __func__, dev_name(req_dev), ret, freq, volt);
+ goto out;
+ }
+
+ ret = _add_vdd_user(tdvfs_info, req_dev, volt);
+ if (ret) {
+ dev_err(target_dev, "%s: vddadd(%s) failed %d[f=%ld, v=%ld]\n",
+ __func__, dev_name(req_dev), ret, freq, volt);
+ _remove_freq_request(tdvfs_info, req_dev,
+ target_dev);
+ goto out;
+ }
+
+ /* Do the actual scaling */
+ ret = _dvfs_scale(req_dev, target_dev, tdvfs_info);
+ if (ret) {
+ dev_err(target_dev, "%s: scale by %s failed %d[f=%ld, v=%ld]\n",
+ __func__, dev_name(req_dev), ret, freq, volt);
+ _remove_freq_request(tdvfs_info, req_dev,
+ target_dev);
+ _remove_vdd_user(tdvfs_info, target_dev);
+ /* Fall through */
+ }
+ /* Fall through */
+out:
+ mutex_unlock(&omap_dvfs_lock);
+ return ret;
+}
+EXPORT_SYMBOL(omap_device_scale);
+
+/**
+ * omap_dvfs_register_device - Add a parent device into dvfs managed list
+ * @dev: Device to be added
+ * @voltdm_name: Name of the voltage domain for the device
+ * @clk_name: Name of the clock for the device
+ *
+ * This function adds a given device into user_list of corresponding
+ * vdd's omap_vdd_dvfs_info strucure. This list is traversed to scale
+ * frequencies of all the devices on a given vdd.
+ *
+ * Returns 0 on success.
+ */
+int __init omap_dvfs_register_device(struct device *dev, char *voltdm_name,
+ char *clk_name)
+{
+ struct omap_vdd_dev_list *temp_dev;
+ struct omap_vdd_dvfs_info *dvfs_info;
+ struct clk *clk = NULL;
+ struct voltagedomain *voltdm;
+ int ret = 0;
+
+ if (!voltdm_name) {
+ dev_err(dev, "%s: Bad voltdm name!\n", __func__);
+ return -EINVAL;
+ }
+ if (!clk_name) {
+ dev_err(dev, "%s: Bad clk name!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Lock me to secure structure changes */
+ mutex_lock(&omap_dvfs_lock);
+
+ voltdm = voltdm_lookup(voltdm_name);
+ if (!voltdm) {
+ dev_warn(dev, "%s: unable to find voltdm %s!\n",
+ __func__, voltdm_name);
+ ret = -EINVAL;
+ goto out;
+ }
+ dvfs_info = _voltdm_to_dvfs_info(voltdm);
+ if (!dvfs_info) {
+ dvfs_info = kzalloc(sizeof(struct omap_vdd_dvfs_info),
+ GFP_KERNEL);
+ if (!dvfs_info) {
+ dev_warn(dev, "%s: unable to alloc memory!\n",
+ __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+ dvfs_info->voltdm = voltdm;
+
+ /* Init the plist */
+ spin_lock_init(&dvfs_info->user_lock);
+ plist_head_init(&dvfs_info->vdd_user_list,
+ &dvfs_info->user_lock);
+ /* Init the device list */
+ INIT_LIST_HEAD(&dvfs_info->dev_list);
+
+ list_add(&dvfs_info->node, &omap_dvfs_info_list);
+ }
+
+ /* If device already added, we dont need to do more.. */
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == dev)
+ goto out;
+ }
+
+ temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL);
+ if (!temp_dev) {
+ dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ clk = clk_get(dev, clk_name);
+ if (IS_ERR_OR_NULL(clk)) {
+ dev_warn(dev, "%s: Bad clk pointer!\n", __func__);
+ kfree(temp_dev);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Initialize priority ordered list */
+ spin_lock_init(&temp_dev->user_lock);
+ plist_head_init(&temp_dev->freq_user_list, &temp_dev->user_lock);
+
+ temp_dev->dev = dev;
+ temp_dev->clk = clk;
+ list_add_tail(&temp_dev->node, &dvfs_info->dev_list);
+
+ /* Fall through */
+out:
+ mutex_unlock(&omap_dvfs_lock);
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/dvfs.h b/arch/arm/mach-omap2/dvfs.h
new file mode 100644
index 0000000..da85c6d
--- /dev/null
+++ b/arch/arm/mach-omap2/dvfs.h
@@ -0,0 +1,38 @@
+/*
+ * OMAP3/OMAP4 DVFS Management Routines
+ *
+ * Author: Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_DVFS_H
+#define __ARCH_ARM_MACH_OMAP2_DVFS_H
+#include <plat/omap_hwmod.h>
+#include "voltage.h"
+
+#ifdef CONFIG_PM
+int omap_dvfs_register_device(struct device *dev, char *voltdm_name,
+ char *clk_name);
+int omap_device_scale(struct device *req_dev, struct device *target_dev,
+ unsigned long rate);
+#else
+static inline int omap_dvfs_register_device(struct omap_hwmod *oh,
+ struct device *dev)
+static inline int omap_dvfs_register_device(struct device *dev,
+ char *voltdm_name, char *clk_name)
+{
+ return -EINVAL;
+}
+static inline int omap_device_scale(struct device *req_dev,
+ struct device *target_dev, unsigned long rate)
+{
+ return -EINVAL;
+}
+#endif
+#endif
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 66868c5..af991ff 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -344,6 +344,13 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
if (c->vcc_aux_disable_is_sleep)
mmc->slots[0].vcc_aux_disable_is_sleep = 1;
+ if (cpu_is_omap44xx()) {
+ if (omap_rev() > OMAP4430_REV_ES1_0)
+ mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
+ if (c->mmc >= 3 && c->mmc <= 5)
+ mmc->slots[0].features |= HSMMC_HAS_48MHZ_MASTER_CLK;
+ }
+
/*
* NOTE: MMC slots should have a Vcc regulator set up.
* This may be from a TWL4030-family chip, another
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 2537090..cd3c00e 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -331,8 +331,13 @@ static void __init omap3_check_revision(void)
static void __init omap4_check_revision(void)
{
u32 idcode;
- u16 hawkeye;
u8 rev;
+ /*
+ * NOTE: OMAP4460+ uses ramp system for identification and hawkeye
+ * variable is reused for the same. Since the values are unique
+ * we continue to use the current system
+ */
+ u16 hawkeye;
/*
* The IC rev detection is done with hawkeye and rev.
@@ -344,10 +349,10 @@ static void __init omap4_check_revision(void)
rev = (idcode >> 28) & 0xf;
/*
- * Few initial ES2.0 samples IDCODE is same as ES1.0
+ * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
* Use ARM register to detect the correct ES version
*/
- if (!rev) {
+ if (!rev && (hawkeye != 0xb94e)) {
idcode = read_cpuid(CPUID_ID);
rev = (idcode & 0xf) - 1;
}
@@ -377,6 +382,15 @@ static void __init omap4_check_revision(void)
omap_chip.oc |= CHIP_IS_OMAP4430ES2_2;
}
break;
+ case 0xb94e:
+ switch (rev) {
+ case 0:
+ default:
+ omap_revision = OMAP4460_REV_ES1_0;
+ omap_chip.oc |= CHIP_IS_OMAP4460ES1_0;
+ break;
+ }
+ break;
default:
/* Unknown default to latest silicon rev as default */
omap_revision = OMAP4430_REV_ES2_2;
diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
new file mode 100644
index 0000000..66f31c3
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
@@ -0,0 +1,41 @@
+/*
+ * OMAP WakeupGen header file
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef OMAP_ARCH_WAKEUPGEN_H
+#define OMAP_ARCH_WAKEUPGEN_H
+
+#define OMAP_WKG_CONTROL_0 0x00
+#define OMAP_WKG_ENB_A_0 0x10
+#define OMAP_WKG_ENB_B_0 0x14
+#define OMAP_WKG_ENB_C_0 0x18
+#define OMAP_WKG_ENB_D_0 0x1c
+#define OMAP_WKG_ENB_SECURE_A_0 0x20
+#define OMAP_WKG_ENB_SECURE_B_0 0x24
+#define OMAP_WKG_ENB_SECURE_C_0 0x28
+#define OMAP_WKG_ENB_SECURE_D_0 0x2c
+#define OMAP_WKG_ENB_A_1 0x410
+#define OMAP_WKG_ENB_B_1 0x414
+#define OMAP_WKG_ENB_C_1 0x418
+#define OMAP_WKG_ENB_D_1 0x41c
+#define OMAP_WKG_ENB_SECURE_A_1 0x420
+#define OMAP_WKG_ENB_SECURE_B_1 0x424
+#define OMAP_WKG_ENB_SECURE_C_1 0x428
+#define OMAP_WKG_ENB_SECURE_D_1 0x42c
+#define OMAP_AUX_CORE_BOOT_0 0x800
+#define OMAP_AUX_CORE_BOOT_1 0x804
+#define OMAP_PTMSYNCREQ_MASK 0xc00
+#define OMAP_PTMSYNCREQ_EN 0xc04
+#define OMAP_TIMESTAMPCYCLELO 0xc08
+#define OMAP_TIMESTAMPCYCLEHI 0xc0c
+
+extern int __init omap_wakeupgen_init(void);
+extern void omap_wakeupgen_irqmask_all(unsigned int cpu, unsigned int set);
+extern void omap_wakeupgen_save(void);
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index e4bd87619..8ebb641 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -13,31 +13,109 @@
#ifndef OMAP_ARCH_OMAP4_COMMON_H
#define OMAP_ARCH_OMAP4_COMMON_H
+#include <asm/proc-fns.h>
/*
- * wfi used in low power code. Directly opcode is used instead
- * of instruction to avoid mulit-omap build break
+ * Secure low power context save/restore API index
*/
-#ifdef CONFIG_THUMB2_KERNEL
-#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory")
-#else
-#define do_wfi() \
- __asm__ __volatile__ (".word 0xe320f003" : : : "memory")
-#endif
+#define HAL_SAVESECURERAM_INDEX 0x1a
+#define HAL_SAVEHW_INDEX 0x1b
+#define HAL_SAVEALL_INDEX 0x1c
+#define HAL_SAVEGIC_INDEX 0x1d
+#define PPA_SERVICE_NS_SMP 0x25
+/*
+ * Secure HAL API flags
+ */
+#define FLAG_START_CRITICAL 0x4
+#define FLAG_IRQFIQ_MASK 0x3
+#define FLAG_IRQ_ENABLE 0x2
+#define FLAG_FIQ_ENABLE 0x1
+#define NO_FLAG 0x0
+
+#ifndef __ASSEMBLER__
#ifdef CONFIG_CACHE_L2X0
-extern void __iomem *l2cache_base;
+extern void __iomem *omap4_get_l2cache_base(void);
#endif
-extern void __iomem *gic_dist_base_addr;
+#ifdef CONFIG_SMP
+extern void __iomem *omap4_get_scu_base(void);
+#else
+static inline void __iomem *omap4_get_scu_base(void)
+{
+ return NULL;
+}
+#endif
+extern void __iomem *omap4_get_gic_dist_base(void);
+extern void __iomem *omap4_get_gic_cpu_base(void);
+extern void __iomem *omap4_get_sar_ram_base(void);
+extern dma_addr_t omap4_secure_ram_phys;
extern void __init gic_init_irq(void);
+extern void gic_cpu_enable(void);
+extern void gic_cpu_disable(void);
+extern void gic_dist_enable(void);
+extern void gic_dist_disable(void);
extern void omap_smc1(u32 fn, u32 arg);
+/*
+ * Read MPIDR: Multiprocessor affinity register
+ */
+static inline unsigned int hard_smp_processor_id(void)
+{
+ unsigned int cpunum;
+
+ asm volatile (
+ "mrc p15, 0, %0, c0, c0, 5\n"
+ : "=r" (cpunum));
+ return cpunum &= 0x0f;
+}
+
#ifdef CONFIG_SMP
/* Needed for secondary core boot */
extern void omap_secondary_startup(void);
extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
extern void omap_auxcoreboot_addr(u32 cpu_addr);
extern u32 omap_read_auxcoreboot0(void);
-#endif
-#endif
+
+#ifdef CONFIG_PM
+extern int omap4_mpuss_init(void);
+extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
+extern void omap4_cpu_suspend(unsigned int cpu, unsigned int save_state);
+extern void omap4_cpu_resume(void);
+extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
+extern u32 omap4_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+#else
+static inline int omap4_enter_lowpower(unsigned int cpu,
+ unsigned int power_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static inline int omap4_mpuss_init(void)
+{
+ return 0;
+}
+
+static inline void omap4_cpu_suspend(unsigned int cpu, unsigned int save_state)
+{
+}
+
+static inline void omap4_cpu_resume(void)
+{
+}
+
+static inline u32 omap_smc2(u32 id, u32 falg, u32 pargs)
+{
+ return 0;
+}
+static inline u32 omap4_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
+#endif /* CONFIG_SMP */
+#endif /* __ASSEMBLER__ */
+#endif /* OMAP_ARCH_OMAP4_COMMON_H */
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 441e79d..b5c8e80 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -38,6 +38,7 @@
#include "io.h"
#include <plat/omap-pm.h>
+#include "voltage.h"
#include "powerdomain.h"
#include "clockdomain.h"
@@ -355,18 +356,22 @@ void __init omap2_init_common_infrastructure(void)
u8 postsetup_state;
if (cpu_is_omap242x()) {
+ omap2xxx_voltagedomains_init();
omap2xxx_powerdomains_init();
omap2xxx_clockdomains_init();
omap2420_hwmod_init();
} else if (cpu_is_omap243x()) {
+ omap2xxx_voltagedomains_init();
omap2xxx_powerdomains_init();
omap2xxx_clockdomains_init();
omap2430_hwmod_init();
} else if (cpu_is_omap34xx()) {
+ omap3xxx_voltagedomains_init();
omap3xxx_powerdomains_init();
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
} else if (cpu_is_omap44xx()) {
+ omap44xx_voltagedomains_init();
omap44xx_powerdomains_init();
omap44xx_clockdomains_init();
omap44xx_hwmod_init();
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 4a6ef6a..01447f6 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -71,9 +71,9 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
mcbsp = id_to_mcbsp_ptr(id);
if (fck_src_id == MCBSP_CLKS_PAD_SRC)
- fck_src_name = "pad_fck";
+ fck_src_name = mcbsp->pdata->clks_pad_src;
else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
- fck_src_name = "prcm_fck";
+ fck_src_name = mcbsp->pdata->clks_prcm_src;
else
return -EINVAL;
@@ -129,12 +129,21 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
pdata->mcbsp_config_type = oh->class->rev;
if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
+ strcpy(pdata->clks_pad_src, "pad_clks_ck");
+ strcpy(pdata->clks_prcm_src, "mcbsp2_sync_mux_ck");
+
if (id == 2)
/* The FIFO has 1024 + 256 locations */
pdata->buffer_size = 0x500;
else
/* The FIFO has 128 locations */
pdata->buffer_size = 0x80;
+ } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) {
+ strcpy(pdata->clks_pad_src, "pad_clks_ck");
+ strcpy(pdata->clks_prcm_src, "mcbsp2_sync_mux_ck");
+
+ /* The FIFO has 128 locations for all instances */
+ pdata->buffer_size = 0x80;
}
oh_device[0] = oh;
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 4976b93..f69cd5c 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -19,7 +19,13 @@
#include <linux/smp.h>
#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+
#include <mach/omap4-common.h>
+#include <mach/omap-wakeupgen.h>
+
+#include "powerdomain.h"
+#include "clockdomain.h"
int platform_cpu_kill(unsigned int cpu)
{
@@ -32,6 +38,12 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
+ unsigned int this_cpu;
+ static struct clockdomain *cpu1_clkdm;
+
+ if (!cpu1_clkdm)
+ cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
+
flush_cache_all();
dsb();
@@ -39,18 +51,26 @@ void platform_cpu_die(unsigned int cpu)
* we're ready for shutdown now, so do it
*/
if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
- printk(KERN_CRIT "Secure clear status failed\n");
+ pr_err("Secure clear status failed\n");
for (;;) {
/*
- * Execute WFI
+ * Enter into low power state
+ * clear all interrupt wakeup sources
*/
- do_wfi();
-
- if (omap_read_auxcoreboot0() == cpu) {
+ omap_wakeupgen_irqmask_all(cpu, 1);
+ gic_cpu_disable();
+ omap4_enter_lowpower(cpu, PWRDM_POWER_OFF);
+ this_cpu = hard_smp_processor_id();
+ if (omap_read_auxcoreboot0() == this_cpu) {
/*
* OK, proper wakeup, we're done
*/
+ omap_wakeupgen_irqmask_all(this_cpu, 0);
+ gic_cpu_enable();
+
+ /* Restore clockdomain to hardware supervised */
+ clkdm_allow_idle(cpu1_clkdm);
break;
}
pr_debug("CPU%u: spurious wakeup call\n", cpu);
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ecfe93c..8ad6957 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -26,11 +26,19 @@
#include <mach/hardware.h>
#include <mach/omap4-common.h>
+#include "clockdomain.h"
+
/* SCU base address */
static void __iomem *scu_base;
static DEFINE_SPINLOCK(boot_lock);
+
+void __iomem *omap4_get_scu_base(void)
+{
+ return scu_base;
+}
+
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
@@ -49,6 +57,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
+ static struct clockdomain *cpu1_clkdm;
+ static bool booted;
/*
* Set synchronisation state between this boot processor
* and the secondary one
@@ -64,7 +74,27 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
omap_modify_auxcoreboot0(0x200, 0xfffffdff);
flush_cache_all();
smp_wmb();
- gic_raise_softirq(cpumask_of(cpu), 1);
+
+ if (!cpu1_clkdm)
+ cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
+
+ /*
+ * The SGI(Software Generated Interrupts) are not wakeup capable
+ * from low power states. This is known limitation on OMAP4 and
+ * needs to be worked around by using software forced clockdomain
+ * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to
+ * software force wakeup. After the wakeup, CPU1 restores its
+ * clockdomain hardware supervised mode.
+ * More details can be found in OMAP4430 TRM - Version J
+ * Section :
+ * 4.3.4.2 Power States of CPU0 and CPU1
+ */
+ if (booted) {
+ clkdm_wakeup(cpu1_clkdm);
+ } else {
+ dsb_sev();
+ booted = true;
+ }
/*
* Now the secondary core is starting up let it run its
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
new file mode 100644
index 0000000..345a55c
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -0,0 +1,319 @@
+/*
+ * OMAP WakeupGen Source file
+ *
+ * The WakeupGen unit is responsible for generating wakeup event from the
+ * incoming interrupts and enable bits. The WakeupGen is implemented in MPU
+ * always-On power domain. The WakeupGen consists of two sub-units, one for
+ * each CPU and manages only SPI interrupts. Hardware requirements is that
+ * the GIC and WakeupGen should be kept in sync for proper operation.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/gic.h>
+
+#include <mach/omap-wakeupgen.h>
+#include <mach/omap4-common.h>
+
+#include "omap4-sar-layout.h"
+
+#define NR_BANKS 4
+#define MAX_IRQS 128
+#define WKG_MASK_ALL 0x00000000
+#define WKG_UNMASK_ALL 0xffffffff
+#define CPU_ENA_OFFSET 0x400
+#define CPU0_ID 0x0
+#define CPU1_ID 0x1
+
+/* WakeupGen Base addres */
+static void __iomem *wakeupgen_base;
+static void __iomem *sar_base;
+static DEFINE_PER_CPU(u32 [NR_BANKS], irqmasks);
+static DEFINE_SPINLOCK(wakeupgen_lock);
+
+/*
+ * Static helper functions
+ */
+
+static inline u32 wakeupgen_readl(u8 idx, u32 cpu)
+{
+ return __raw_readl(wakeupgen_base + OMAP_WKG_ENB_A_0 +
+ (cpu * CPU_ENA_OFFSET) + (idx * 4));
+}
+
+static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu)
+{
+ __raw_writel(val, wakeupgen_base + OMAP_WKG_ENB_A_0 +
+ (cpu * CPU_ENA_OFFSET) + (idx * 4));
+}
+
+static inline void sar_writel(u32 val, u32 offset, u8 idx)
+{
+ __raw_writel(val, sar_base + offset + (idx * 4));
+}
+
+static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
+{
+ u8 i;
+
+ for (i = 0; i < NR_BANKS; i++)
+ wakeupgen_writel(reg, i, cpu);
+}
+
+static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index)
+{
+ unsigned int spi_irq;
+
+ /*
+ * PPIs and SGIs are not supported
+ */
+ if (irq < OMAP44XX_IRQ_GIC_START)
+ return -EINVAL;
+
+ /*
+ * Subtract the GIC offset
+ */
+ spi_irq = irq - OMAP44XX_IRQ_GIC_START;
+ if (spi_irq > MAX_IRQS) {
+ pr_err("omap wakeupGen: Invalid IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ /*
+ * Each wakeup gen register controls 32
+ * interrupts. i.e 1 bit per SPI IRQ
+ */
+ *reg_index = spi_irq >> 5;
+ *bit_posn = spi_irq %= 32;
+
+ return 0;
+}
+
+static void _wakeupgen_clear(unsigned int irq)
+{
+ unsigned int cpu = smp_processor_id();
+ u32 val, bit_number;
+ u8 i;
+
+ if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
+ return;
+
+ val = wakeupgen_readl(i, cpu);
+ val &= ~BIT(bit_number);
+ wakeupgen_writel(val, i, cpu);
+}
+
+static void _wakeupgen_set(unsigned int irq)
+{
+ unsigned int cpu = smp_processor_id();
+ u32 val, bit_number;
+ u8 i;
+
+ if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
+ return;
+
+ val = wakeupgen_readl(i, cpu);
+ val |= BIT(bit_number);
+ wakeupgen_writel(val, i, cpu);
+}
+
+static void _wakeupgen_save_masks(unsigned int cpu)
+{
+ u8 i;
+
+ for (i = 0; i < NR_BANKS; i++)
+ per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);
+}
+
+static void _wakeupgen_restore_masks(unsigned int cpu)
+{
+ u8 i;
+
+ for (i = 0; i < NR_BANKS; i++)
+ wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);
+}
+
+/*
+ * Architecture specific Mask extensiom
+ */
+static void wakeupgen_mask(struct irq_data *d)
+{
+ spin_lock(&wakeupgen_lock);
+ _wakeupgen_clear(d->irq);
+ spin_unlock(&wakeupgen_lock);
+}
+
+/*
+ * Architecture specific Unmask extensiom
+ */
+static void wakeupgen_unmask(struct irq_data *d)
+{
+
+ spin_lock(&wakeupgen_lock);
+ _wakeupgen_set(d->irq);
+ spin_unlock(&wakeupgen_lock);
+}
+
+#ifdef CONFIG_PM
+/*
+ * Architecture specific set_wake extension
+ */
+static int wakeupgen_set_wake(struct irq_data *d, unsigned int on)
+{
+ spin_lock(&wakeupgen_lock);
+ if (on)
+ _wakeupgen_set(d->irq);
+ else
+ _wakeupgen_clear(d->irq);
+ spin_unlock(&wakeupgen_lock);
+
+ return 0;
+}
+
+#else
+#define wakeupgen_set_wake NULL
+#endif
+
+/**
+ * omap_wakeupgen_irqmask_all() - Mask or unmask interrupts
+ * @cpu - CPU ID
+ * @set - The IRQ register mask.
+ * 0 = Mask all interrupts on the 'cpu'
+ * 1 = Unmask all interrupts on the 'cpu'
+ *
+ * Ensure that the initial mask is maintained. This is faster than
+ * iterating through GIC rgeisters to arrive at the correct masks
+ */
+void omap_wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
+{
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return;
+
+ spin_lock(&wakeupgen_lock);
+ if (set) {
+ _wakeupgen_save_masks(cpu);
+ _wakeupgen_set_all(cpu, WKG_MASK_ALL);
+ } else {
+ _wakeupgen_set_all(cpu, WKG_UNMASK_ALL);
+ _wakeupgen_restore_masks(cpu);
+ }
+ spin_unlock(&wakeupgen_lock);
+}
+
+/*
+ * Initialse the wakeupgen module
+ */
+int __init omap_wakeupgen_init(void)
+{
+ u8 i;
+
+ /* Not supported on on OMAP4 ES1.0 silicon */
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n");
+ return -EPERM;
+ }
+
+ /* Static mapping, never released */
+ wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K);
+ if (WARN_ON(!wakeupgen_base))
+ return -ENODEV;
+
+ /* Clear all IRQ bitmasks at wakeupGen level */
+ for (i = 0; i < NR_BANKS; i++) {
+ wakeupgen_writel(0, i, CPU0_ID);
+ wakeupgen_writel(0, i, CPU1_ID);
+ }
+
+ /*
+ * Override gic architecture specific fucntioms to add
+ * OMAP WakeupGen interrupt controller along with GIC
+ */
+ gic_arch_extn.irq_mask = wakeupgen_mask;
+ gic_arch_extn.irq_unmask = wakeupgen_unmask;
+ gic_arch_extn.irq_set_wake = wakeupgen_set_wake;
+
+ return 0;
+}
+
+/**
+ * omap_wakeupgen_save() - WakeupGen context save function
+ *
+ * Save WakewupGen context in SAR BANK3. Restore is done by ROM code.
+ * WakeupGen IP is integrated along with GIC to manage the
+ * interrupt wakeups from CPU low power states. It's located in
+ * always ON power domain. It manages masking/unmasking of
+ * Shared peripheral interrupts(SPI).So the interrupt enable/disable
+ * control should be in sync and consistent at WakeupGen and GIC so
+ * that interrupts are not lost. Hence GIC and WakeupGen are saved
+ * and restored together.
+
+ * During normal operation, WakeupGen delivers external interrupts
+ * directly to the GIC. When the CPU asserts StandbyWFI, indicating
+ * it wants to enter lowpower state, the Standby Controller checks
+ * with the WakeupGen unit using the idlereq/idleack handshake to make
+ * sure there is no incoming interrupts.
+ */
+
+void omap_wakeupgen_save(void)
+{
+ u8 i;
+ u32 val;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return;
+
+ if (!sar_base)
+ sar_base = omap4_get_sar_ram_base();
+
+ for (i = 0; i < NR_BANKS; i++) {
+ /* Save the CPUx interrupt mask for IRQ 0 to 127 */
+ val = wakeupgen_readl(i, 0);
+ sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i);
+ val = wakeupgen_readl(i, 1);
+ sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i);
+
+ /*
+ * Disable the secure interrupts for CPUx. The restore
+ * code blindly restores secure and non-secure interrupt
+ * masks from SAR RAM. Secure interrupts are not suppose
+ * to be enabled from HLOS. So overwrite the SAR location
+ * so that the secure interrupt remains disabled.
+ */
+ sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i);
+ sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i);
+ }
+
+ /* Save AuxBoot* registers */
+ val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
+ val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
+
+ /* Save SyncReq generation logic */
+ val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
+ val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
+
+ /* Save SyncReq generation logic */
+ val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK);
+ __raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET);
+ val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN);
+ __raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET);
+
+ /* Set the Backup Bit Mask status */
+ val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
+ val |= SAR_BACKUP_STATUS_WAKEUPGEN;
+ __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
+}
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
new file mode 100644
index 0000000..2523b11
--- /dev/null
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
@@ -0,0 +1,275 @@
+/*
+ * OMAP2PLUS cpufreq driver
+ *
+ * CPU frequency scaling for OMAP using OPP information
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2011 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@ti.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/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+#include <linux/cpu.h>
+
+#include <asm/system.h>
+#include <asm/smp_plat.h>
+#include <asm/cpu.h>
+
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
+#include <plat/common.h>
+
+#include <mach/hardware.h>
+
+#include "dvfs.h"
+
+static struct cpufreq_frequency_table *freq_table;
+static atomic_t freq_table_users = ATOMIC_INIT(0);
+static struct clk *mpu_clk;
+static char *mpu_clk_name;
+static struct device *mpu_dev;
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (!freq_table)
+ return -EINVAL;
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int omap_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu >= NR_CPUS)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+ return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int i;
+ int ret = 0;
+ struct cpufreq_freqs freqs;
+
+ if (!freq_table) {
+ dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
+ policy->cpu);
+ return -EINVAL;
+ }
+
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &i);
+ if (ret) {
+ dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
+ __func__, policy->cpu, target_freq, ret);
+ return ret;
+ }
+ freqs.new = freq_table[i].frequency;
+ if (!freqs.new) {
+ dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
+ policy->cpu, target_freq);
+ return -EINVAL;
+ }
+
+ freqs.old = omap_getspeed(policy->cpu);
+ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new && policy->cur == freqs.new)
+ return ret;
+
+ if (!is_smp()) {
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ goto set_freq;
+ }
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+
+set_freq:
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
+#endif
+
+ ret = omap_device_scale(mpu_dev, mpu_dev, freqs.new * 1000);
+
+ /*
+ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
+ * won't get updated when UP machine cpufreq build with
+ * CONFIG_SMP enabled. Below code is added only to manage that
+ * scenario
+ */
+ freqs.new = omap_getspeed(policy->cpu);
+ if (!is_smp()) {
+ loops_per_jiffy =
+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ goto skip_lpj;
+ }
+
+#ifdef CONFIG_SMP
+ /*
+ * Note that loops_per_jiffy is not updated on SMP systems in
+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
+ * on frequency transition. We need to update all dependent CPUs.
+ */
+ for_each_cpu(i, policy->cpus)
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
+ freqs.old, freqs.new);
+#endif
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+
+skip_lpj:
+ return ret;
+}
+
+static inline void freq_table_free(void)
+{
+ if (atomic_dec_and_test(&freq_table_users))
+ opp_free_cpufreq_table(mpu_dev, &freq_table);
+}
+
+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+
+ mpu_clk = clk_get(NULL, mpu_clk_name);
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+ if (policy->cpu >= NR_CPUS) {
+ result = -EINVAL;
+ goto fail_ck;
+ }
+
+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
+
+ if (atomic_inc_return(&freq_table_users) == 1)
+ result = opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+ if (result) {
+ dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
+ __func__, policy->cpu, result);
+ goto fail_ck;
+ }
+
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (result)
+ goto fail_table;
+
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(policy->cpu);
+
+ /*
+ * On OMAP SMP configuartion, both processors share the voltage
+ * and clock. So both CPUs needs to be scaled together and hence
+ * needs software co-ordination. Use cpufreq affected_cpus
+ * interface to handle this scenario. Additional is_smp() check
+ * is to keep SMP_ON_UP build working.
+ */
+ if (is_smp()) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_setall(policy->cpus);
+ }
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ return 0;
+
+fail_table:
+ freq_table_free();
+fail_ck:
+ clk_put(mpu_clk);
+ return result;
+}
+
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ freq_table_free();
+ clk_put(mpu_clk);
+ return 0;
+}
+
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver omap_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = omap_verify_speed,
+ .target = omap_target,
+ .get = omap_getspeed,
+ .init = omap_cpu_init,
+ .exit = omap_cpu_exit,
+ .name = "omap2plus",
+ .attr = omap_cpufreq_attr,
+};
+
+static int __init omap_cpufreq_init(void)
+{
+ if (cpu_is_omap24xx())
+ mpu_clk_name = "virt_prcm_set";
+ else if (cpu_is_omap34xx())
+ mpu_clk_name = "dpll1_ck";
+ else if (cpu_is_omap443x())
+ mpu_clk_name = "dpll_mpu_ck";
+ else if (cpu_is_omap446x())
+ mpu_clk_name = "virt_dpll_mpu_ck";
+
+ if (!mpu_clk_name) {
+ pr_err("%s: unsupported Silicon?\n", __func__);
+ return -EINVAL;
+ }
+
+ mpu_dev = omap2_get_mpuss_device();
+ if (!mpu_dev) {
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+ }
+
+ return cpufreq_register_driver(&omap_driver);
+}
+
+static void __exit omap_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&omap_driver);
+}
+
+MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs");
+MODULE_LICENSE("GPL");
+late_initcall(omap_cpufreq_init);
+module_exit(omap_cpufreq_exit);
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 9ef8c29..c3e65f6 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -18,34 +18,84 @@
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
+#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
+#include <mach/omap-wakeupgen.h>
+
+#include "omap4-sar-layout.h"
+#include "clockdomain.h"
#ifdef CONFIG_CACHE_L2X0
-void __iomem *l2cache_base;
+#define L2X0_POR_OFFSET_VALUE 0x9
+static void __iomem *l2cache_base;
#endif
-void __iomem *gic_dist_base_addr;
+static void __iomem *gic_dist_base_addr;
+static void __iomem *gic_cpu_base;
+static void __iomem *sar_ram_base;
+static struct clockdomain *l4_secure_clkdm;
+void __iomem *omap4_get_gic_dist_base(void)
+{
+ return gic_dist_base_addr;
+}
+
+void __iomem *omap4_get_gic_cpu_base(void)
+{
+ return gic_cpu_base;
+}
void __init gic_init_irq(void)
{
- void __iomem *gic_cpu_base;
/* Static mapping, never released */
gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
- BUG_ON(!gic_dist_base_addr);
+ if (WARN_ON(!gic_dist_base_addr))
+ return;
/* Static mapping, never released */
gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
- BUG_ON(!gic_cpu_base);
+ if (WARN_ON(!gic_cpu_base))
+ return;
+
+ omap_wakeupgen_init();
gic_init(0, 29, gic_dist_base_addr, gic_cpu_base);
}
+/*
+ * FIXME: Remove this GIC APIs once common GIG library starts
+ * supporting it.
+ */
+void gic_cpu_enable(void)
+{
+ __raw_writel(0xf0, gic_cpu_base + GIC_CPU_PRIMASK);
+ __raw_writel(1, gic_cpu_base + GIC_CPU_CTRL);
+}
+
+void gic_cpu_disable(void)
+{
+ __raw_writel(0, gic_cpu_base + GIC_CPU_CTRL);
+}
+
+void gic_dist_enable(void)
+{
+ __raw_writel(0x1, gic_dist_base_addr + GIC_DIST_CTRL);
+}
+void gic_dist_disable(void)
+{
+ __raw_writel(0, gic_dist_base_addr + GIC_CPU_CTRL);
+}
+
#ifdef CONFIG_CACHE_L2X0
+void __iomem *omap4_get_l2cache_base(void)
+{
+ return l2cache_base;
+}
+
static void omap4_l2x0_disable(void)
{
/* Disable PL310 L2 Cache controller */
@@ -61,6 +111,8 @@ static void omap4_l2x0_set_debug(unsigned long val)
static int __init omap_l2_cache_init(void)
{
u32 aux_ctrl = 0;
+ u32 por_ctrl = 0;
+ u32 lockdown = 0;
/*
* To avoid code running on other OMAPs in
@@ -71,30 +123,70 @@ static int __init omap_l2_cache_init(void)
/* Static mapping, never released */
l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
- BUG_ON(!l2cache_base);
+ if (WARN_ON(!l2cache_base))
+ return -ENODEV;
/*
* 16-way associativity, parity disabled
* Way size - 32KB (es1.0)
* Way size - 64KB (es2.0 +)
*/
- aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
- (0x1 << 25) |
- (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
- (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
+ aux_ctrl = readl_relaxed(l2cache_base + L2X0_AUX_CTRL);
if (omap_rev() == OMAP4430_REV_ES1_0) {
aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
- } else {
- aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
- (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
- (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
- (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
- (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
+ goto skip_aux_por_api;
+ }
+
+ /*
+ * Drop instruction prefetch hint since it degrades the
+ * the performance.
+ */
+ aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
+ (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
+ (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+ (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
+
+ omap_smc1(0x109, aux_ctrl);
+
+ /* Setup POR Control register */
+ por_ctrl = readl_relaxed(l2cache_base + L2X0_PREFETCH_CTRL);
+
+ /*
+ * Double linefill is available only on OMAP4460 L2X0.
+ * Undocumented bit 25 is set for better performance.
+ */
+ if (cpu_is_omap446x())
+ por_ctrl |= ((1 << L2X0_PREFETCH_DATA_PREFETCH_SHIFT) |
+ (1 << L2X0_PREFETCH_DOUBLE_LINEFILL_SHIFT) |
+ (1 << 25));
+
+ if (cpu_is_omap446x() || (omap_rev() >= OMAP4430_REV_ES2_2)) {
+ por_ctrl |= L2X0_POR_OFFSET_VALUE;
+ omap_smc1(0x113, por_ctrl);
+ }
+
+ if (cpu_is_omap446x()) {
+ writel_relaxed(0xa5a5, l2cache_base + 0x900);
+ writel_relaxed(0xa5a5, l2cache_base + 0x908);
+ writel_relaxed(0xa5a5, l2cache_base + 0x904);
+ writel_relaxed(0xa5a5, l2cache_base + 0x90C);
+ }
+
+ /*
+ * FIXME: Temporary WA for OMAP4460 stability issue.
+ * Lock-down specific L2 cache ways which makes effective
+ * L2 size as 512 KB instead of 1 MB
+ */
+ if (cpu_is_omap446x()) {
+ lockdown = 0xa5a5;
+ writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_D0);
+ writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_D1);
+ writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_I0);
+ writel_relaxed(lockdown, l2cache_base + L2X0_LOCKDOWN_WAY_I1);
}
- if (omap_rev() != OMAP4430_REV_ES1_0)
- omap_smc1(0x109, aux_ctrl);
+skip_aux_por_api:
/* Enable PL310 L2 Cache controller */
omap_smc1(0x102, 0x1);
@@ -111,3 +203,80 @@ static int __init omap_l2_cache_init(void)
}
early_initcall(omap_l2_cache_init);
#endif
+
+void __iomem *omap4_get_sar_ram_base(void)
+{
+ return sar_ram_base;
+}
+
+/*
+ * SAR RAM used to save and restore the HW
+ * context in low power modes
+ */
+static int __init omap4_sar_ram_init(void)
+{
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ /* Static mapping, never released */
+ sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_8K);
+ if (WARN_ON(!sar_ram_base))
+ return -ENODEV;
+
+ l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+
+ return 0;
+}
+early_initcall(omap4_sar_ram_init);
+
+
+/*
+ * omap4_sec_dispatcher: Routine to dispatch low power secure
+ * service routines
+ *
+ * @idx: The HAL API index
+ * @flag: The flag indicating criticality of operation
+ * @nargs: Number of valid arguments out of four.
+ * @arg1, arg2, arg3 args4: Parameters passed to secure API
+ *
+ * Return the error value on success/failure
+ */
+u32 omap4_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
+ u32 arg3, u32 arg4)
+{
+ u32 ret;
+ u32 param[5];
+
+ param[0] = nargs;
+ param[1] = arg1;
+ param[2] = arg2;
+ param[3] = arg3;
+ param[4] = arg4;
+
+ /*
+ * Put l4 secure to software wakeup so that secure
+ * modules are accessible
+ */
+ clkdm_wakeup(l4_secure_clkdm);
+
+ /*
+ * Secure API needs physical address
+ * pointer for the parameters
+ */
+ flush_cache_all();
+ outer_clean_range(__pa(param), __pa(param + 5));
+
+ ret = omap_smc2(idx, flag, __pa(param));
+
+ /*
+ * Restore l4 secure to hardware superwised to allow
+ * secure modules idle
+ */
+ clkdm_allow_idle(l4_secure_clkdm);
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
new file mode 100644
index 0000000..bf98bf2
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
@@ -0,0 +1,526 @@
+/*
+ * OMAP4 MPUSS low power code
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU
+ * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller,
+ * CPU0 and CPU1 LPRM modules.
+ * CPU0, CPU1 and MPUSS each have there own power domain and
+ * hence multiple low power combinations of MPUSS are possible.
+ *
+ * The CPU0 and CPU1 can't support Closed switch Retention (CSWR)
+ * because the mode is not supported by hw constraints of dormant
+ * mode. While waking up from the dormant mode, a reset signal
+ * to the Cortex-A9 processor must be asserted by the external
+ * power controller.
+ *
+ * With architectural inputs and hardware recommendations, only
+ * below modes are supported from power gain vs latency point of view.
+ *
+ * CPU0 CPU1 MPUSS
+ * ----------------------------------------------
+ * ON ON ON
+ * ON(Inactive) OFF ON(Inactive)
+ * OFF OFF CSWR
+ * OFF OFF OSWR (*TBD)
+ * OFF OFF OFF
+ * ----------------------------------------------
+ *
+ * Note: CPU0 is the master core and it is the last CPU to go down
+ * and first to wake-up when MPUSS low power states are excercised
+ *
+ *
+ * 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/kernel.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/tlbflush.h>
+#include <asm/smp_scu.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <plat/omap44xx.h>
+#include <mach/omap4-common.h>
+#include <mach/omap-wakeupgen.h>
+
+#include "omap4-sar-layout.h"
+#include "pm.h"
+#include "powerdomain.h"
+
+#ifdef CONFIG_SMP
+
+#define GIC_MASK_ALL 0x0
+#define GIC_ISR_NON_SECURE 0xffffffff
+#define SPI_ENABLE_SET_OFFSET 0x04
+#define PPI_PRI_OFFSET 0x1c
+#define SPI_PRI_OFFSET 0x20
+#define SPI_TARGET_OFFSET 0x20
+#define SPI_CONFIG_OFFSET 0x20
+
+/* GIC save SAR bank base */
+static struct powerdomain *mpuss_pd;
+/*
+ * Maximum Secure memory storage size.
+ */
+#define OMAP4_SECURE_RAM_STORAGE (88 * SZ_1K)
+/*
+ * Physical address of secure memory storage
+ */
+dma_addr_t omap4_secure_ram_phys;
+static void *secure_ram;
+
+/* Variables to store maximum spi(Shared Peripheral Interrupts) registers. */
+static u32 max_spi_irq, max_spi_reg;
+
+struct omap4_cpu_pm_info {
+ struct powerdomain *pwrdm;
+ void __iomem *scu_sar_addr;
+ void __iomem *l1_sar_addr;
+};
+
+static void __iomem *gic_dist_base;
+static void __iomem *sar_base;
+
+static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
+
+/* Helper functions */
+static inline void sar_writel(u32 val, u32 offset, u8 idx)
+{
+ __raw_writel(val, sar_base + offset + 4 * idx);
+}
+
+static inline u32 gic_readl(u32 offset, u8 idx)
+{
+ return __raw_readl(gic_dist_base + offset + 4 * idx);
+}
+
+/*
+ * Set the CPUx powerdomain's previous power state
+ */
+static inline void set_cpu_next_pwrst(unsigned int cpu_id,
+ unsigned int power_state)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+
+ pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
+}
+
+/*
+ * Read CPU's previous power state
+ */
+static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+
+ return pwrdm_read_prev_pwrst(pm_info->pwrdm);
+}
+
+/*
+ * Clear the CPUx powerdomain's previous power state
+ */
+static inline void clear_cpu_prev_pwrst(unsigned int cpu_id)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+
+ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
+}
+
+/*
+ * Store the SCU power status value to scratchpad memory
+ */
+static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+ u32 scu_pwr_st, l1_state;
+
+ switch (cpu_state) {
+ case PWRDM_POWER_RET:
+ scu_pwr_st = SCU_PM_DORMANT;
+ l1_state = 0x00;
+ break;
+ case PWRDM_POWER_OFF:
+ scu_pwr_st = SCU_PM_POWEROFF;
+ l1_state = 0xff;
+ break;
+ case PWRDM_POWER_ON:
+ case PWRDM_POWER_INACTIVE:
+ default:
+ scu_pwr_st = SCU_PM_NORMAL;
+ l1_state = 0x00;
+ break;
+ }
+
+ __raw_writel(scu_pwr_st, pm_info->scu_sar_addr);
+ __raw_writel(scu_pwr_st, pm_info->l1_sar_addr);
+}
+
+/*
+ * Save GIC context in SAR RAM. Restore is done by ROM code
+ * GIC is lost only when MPU hits OSWR or OFF. It consists
+ * of a distributor and a per-CPU interface module. The GIC
+ * save restore is optimised to save only necessary registers.
+ */
+static void gic_save_context(void)
+{
+ u8 i;
+ u32 val;
+
+ /*
+ * Interrupt Clear Enable registers are inverse of set enable
+ * and hence not needed to be saved. ROM code programs it
+ * based on Set Enable register values.
+ */
+
+ /* Save CPU 0 Interrupt Set Enable register */
+ val = gic_readl(GIC_DIST_ENABLE_SET, 0);
+ sar_writel(val, ICDISER_CPU0_OFFSET, 0);
+
+ /* Disable interrupts on CPU1 */
+ sar_writel(GIC_MASK_ALL, ICDISER_CPU1_OFFSET, 0);
+
+ /* Save all SPI Set Enable register */
+ for (i = 0; i < max_spi_reg; i++) {
+ val = gic_readl(GIC_DIST_ENABLE_SET + SPI_ENABLE_SET_OFFSET, i);
+ sar_writel(val, ICDISER_SPI_OFFSET, i);
+ }
+
+ /*
+ * Interrupt Priority Registers
+ * Secure sw accesses, last 5 bits of the 8 bits (bit[7:3] are used)
+ * Non-Secure sw accesses, last 4 bits (i.e. bits[7:4] are used)
+ * But the Secure Bits[7:3] are shifted by 1 in Non-Secure access.
+ * Secure (bits[7:3] << 1)== Non Secure bits[7:4]
+ * Hence right shift the value by 1 while saving the priority
+ */
+
+ /* Save SGI priority registers (Software Generated Interrupt) */
+ for (i = 0; i < 4; i++) {
+ val = gic_readl(GIC_DIST_PRI, i);
+
+ /* Save the priority bits of the Interrupts */
+ sar_writel(val >> 0x1, ICDIPR_SFI_CPU0_OFFSET, i);
+
+ /* Disable the interrupts on CPU1 */
+ sar_writel(GIC_MASK_ALL, ICDIPR_SFI_CPU1_OFFSET, i);
+ }
+
+ /* Save PPI priority registers (Private Peripheral Intterupts) */
+ val = gic_readl(GIC_DIST_PRI + PPI_PRI_OFFSET, 0);
+ sar_writel(val >> 0x1, ICDIPR_PPI_CPU0_OFFSET, 0);
+ sar_writel(GIC_MASK_ALL, ICDIPR_PPI_CPU1_OFFSET, 0);
+
+ /* SPI priority registers - 4 interrupts/register */
+ for (i = 0; i < (max_spi_irq / 4); i++) {
+ val = gic_readl((GIC_DIST_PRI + SPI_PRI_OFFSET), i);
+ sar_writel(val >> 0x1, ICDIPR_SPI_OFFSET, i);
+ }
+
+ /* SPI Interrupt Target registers - 4 interrupts/register */
+ for (i = 0; i < (max_spi_irq / 4); i++) {
+ val = gic_readl((GIC_DIST_TARGET + SPI_TARGET_OFFSET), i);
+ sar_writel(val, ICDIPTR_SPI_OFFSET, i);
+ }
+
+ /* SPI Interrupt Congigeration eegisters- 16 interrupts/register */
+ for (i = 0; i < (max_spi_irq / 16); i++) {
+ val = gic_readl((GIC_DIST_CONFIG + SPI_CONFIG_OFFSET), i);
+ sar_writel(val, ICDICFR_OFFSET, i);
+ }
+
+ /* Set the Backup Bit Mask status for GIC */
+ val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
+ val |= (SAR_BACKUP_STATUS_GIC_CPU0 | SAR_BACKUP_STATUS_GIC_CPU1);
+ __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
+}
+/*
+ * API to save GIC and Wakeupgen using secure API
+ * for HS/EMU device
+ */
+static void save_gic_wakeupgen_secure(void)
+{
+ u32 ret;
+ ret = omap4_secure_dispatcher(HAL_SAVEGIC_INDEX,
+ FLAG_IRQFIQ_MASK | FLAG_START_CRITICAL,
+ 0, 0, 0, 0, 0);
+ if (!ret)
+ pr_debug("GIC and Wakeupgen context save failed\n");
+}
+
+/*
+ * API to save Secure RAM using secure API
+ * for HS/EMU device
+ */
+static void save_secure_ram(void)
+{
+ u32 ret;
+ ret = omap4_secure_dispatcher(HAL_SAVESECURERAM_INDEX,
+ FLAG_IRQFIQ_MASK | FLAG_START_CRITICAL,
+ 1, omap4_secure_ram_phys, 0, 0, 0);
+ if (!ret)
+ pr_debug("Secure ram context save failed\n");
+}
+
+/*
+ * OMAP4 MPUSS Low Power Entry Function
+ *
+ * The purpose of this function is to manage low power programming
+ * of OMAP4 MPUSS subsystem
+ * Paramenters:
+ * cpu : CPU ID
+ * power_state: Targetted Low power state.
+ *
+ * MPUSS Low power states
+ * The basic rule is that the MPUSS power domain must be at the higher or
+ * equal power state (state that consume more power) than the higher of the
+ * two CPUs. For example, it is illegal for system power to be OFF, while
+ * the power of one or both of the CPU is DORMANT. When an illegal state is
+ * entered, then the hardware behavior is unpredictable.
+ *
+ * MPUSS state for the context save
+ * save_state =
+ * 0 - Nothing lost and no need to save: MPUSS INACTIVE
+ * 1 - CPUx L1 and logic lost: MPUSS CSWR
+ * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
+ */
+int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
+{
+ unsigned int save_state = 0;
+ unsigned int wakeup_cpu;
+
+ if ((cpu >= NR_CPUS) || (omap_rev() == OMAP4430_REV_ES1_0))
+ goto ret;
+
+ switch (power_state) {
+ case PWRDM_POWER_ON:
+ case PWRDM_POWER_INACTIVE:
+ save_state = 0;
+ break;
+ case PWRDM_POWER_OFF:
+ save_state = 1;
+ break;
+ case PWRDM_POWER_RET:
+ default:
+ /*
+ * CPUx CSWR is invalid hardware state. Also CPUx OSWR
+ * doesn't make much scense, since logic is lost and $L1
+ * needs to be cleaned because of coherency. This makes
+ * CPUx OSWR equivalent to CPUX OFF and hence not supported
+ */
+ WARN_ON(1);
+ goto ret;
+ }
+
+ /*
+ * MPUSS book keeping should be executed by master
+ * CPU only which is also the last CPU to go down.
+ */
+ if (cpu)
+ goto cpu_prepare;
+
+ pwrdm_pre_transition();
+
+ /*
+ * Check MPUSS next state and save GIC if needed
+ * GIC lost during MPU OFF and OSWR
+ */
+ pwrdm_clear_all_prev_pwrst(mpuss_pd);
+ if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) {
+ if (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF) {
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ save_gic_wakeupgen_secure();
+ } else {
+ omap_wakeupgen_save();
+ gic_save_context();
+ }
+ }
+ }
+ if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ save_secure_ram();
+ save_gic_wakeupgen_secure();
+ } else {
+ omap_wakeupgen_save();
+ gic_save_context();
+ }
+ save_state = 3;
+ }
+
+cpu_prepare:
+ clear_cpu_prev_pwrst(cpu);
+ set_cpu_next_pwrst(cpu, power_state);
+ scu_pwrst_prepare(cpu, power_state);
+
+ /*
+ * Call low level function with targeted CPU id
+ * and its low power state.
+ */
+ omap4_cpu_suspend(cpu, save_state);
+
+ /*
+ * Restore the CPUx power state to ON otherwise CPUx
+ * power domain can transitions to programmed low power
+ * state while doing WFI outside the low powe code. On
+ * secure devices, CPUx does WFI which can result in
+ * domain transition
+ */
+ wakeup_cpu = hard_smp_processor_id();
+ set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
+
+ /* If !master cpu return to hotplug-path */
+ if (wakeup_cpu)
+ goto ret;
+
+ /* Check MPUSS previous power state and enable GIC if needed */
+ if (pwrdm_read_prev_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+ /* Clear SAR BACKUP status */
+ __raw_writel(0x0, sar_base + SAR_BACKUP_STATUS_OFFSET);
+ /* Enable GIC distributor and inteface on CPU0*/
+ gic_cpu_enable();
+ gic_dist_enable();
+ }
+
+ pwrdm_post_transition();
+
+ret:
+ return 0;
+}
+
+static void save_l2x0_auxctrl(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Save the L2X0 AUXCTRL value to SAR memory. Its used to
+ * in every restore patch MPUSS OFF path.
+ */
+ void __iomem *l2x0_base = omap4_get_l2cache_base();
+ u32 val;
+
+ val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
+ __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
+#endif
+}
+
+/*
+ * Initialise OMAP4 MPUSS
+ */
+int __init omap4_mpuss_init(void)
+{
+ struct omap4_cpu_pm_info *pm_info;
+ u8 i;
+
+ /* Get GIC and SAR RAM base addresses */
+ sar_base = omap4_get_sar_ram_base();
+ gic_dist_base = omap4_get_gic_dist_base();
+
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+ return -ENODEV;
+ }
+
+ /* Initilaise per CPU PM information */
+ pm_info = &per_cpu(omap4_pm_info, 0x0);
+ pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
+ pm_info->l1_sar_addr = sar_base + L1_OFFSET0;
+ pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
+ if (!pm_info->pwrdm) {
+ pr_err("Lookup failed for CPU0 pwrdm\n");
+ return -ENODEV;
+ }
+
+ /* Clear CPU previous power domain state */
+ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
+
+ /* Initialise CPU0 power domain state to ON */
+ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+
+ pm_info = &per_cpu(omap4_pm_info, 0x1);
+ pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
+ pm_info->l1_sar_addr = sar_base + L1_OFFSET1;
+ pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
+ if (!pm_info->pwrdm) {
+ pr_err("Lookup failed for CPU1 pwrdm\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Check the OMAP type and store it to scratchpad
+ */
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ /* Memory not released */
+ secure_ram = dma_alloc_coherent(NULL, OMAP4_SECURE_RAM_STORAGE,
+ (dma_addr_t *)&omap4_secure_ram_phys, GFP_ATOMIC);
+ if (!secure_ram)
+ pr_err("Unable to allocate secure ram storage\n");
+ writel(0x1, sar_base + OMAP_TYPE_OFFSET);
+ } else {
+ writel(0x0, sar_base + OMAP_TYPE_OFFSET);
+ }
+
+ /* Clear CPU previous power domain state */
+ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
+
+ /* Initialise CPU1 power domain state to ON */
+ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+
+ /*
+ * Program the wakeup routine address for the CPU0 and CPU1
+ * used for OFF or DORMANT wakeup. Wakeup routine address
+ * is fixed so programit in init itself.
+ */
+ __raw_writel(virt_to_phys(omap4_cpu_resume),
+ sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+ __raw_writel(virt_to_phys(omap4_cpu_resume),
+ sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET);
+
+ mpuss_pd = pwrdm_lookup("mpu_pwrdm");
+ if (!mpuss_pd) {
+ pr_err("Failed to get lookup for MPUSS pwrdm\n");
+ return -ENODEV;
+ }
+
+ /* Clear CPU previous power domain state */
+ pwrdm_clear_all_prev_pwrst(mpuss_pd);
+
+ /*
+ * Find out how many interrupts are supported.
+ * OMAP4 supports max of 128 SPIs where as GIC can support
+ * up to 1020 interrupt sources. On OMAP4, maximum SPIs are
+ * fused in DIST_CTR bit-fields as 128. Hence the code is safe
+ * from reserved register writes since its well within 1020.
+ */
+ max_spi_reg = __raw_readl(gic_dist_base + GIC_DIST_CTR) & 0x1f;
+ max_spi_irq = max_spi_reg * 32;
+
+ /*
+ * Mark the PPI and SPI interrupts as non-secure.
+ * program the SAR locations for interrupt security registers to
+ * reflect the same.
+ */
+ if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
+ sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU0_OFFSET, 0);
+ sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU1_OFFSET, 0);
+ for (i = 0; i < max_spi_reg; i++)
+ sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
+ }
+ save_l2x0_auxctrl();
+
+ return 0;
+}
+
+#endif
+
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
new file mode 100644
index 0000000..0ded2cf
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -0,0 +1,70 @@
+/*
+ * omap4-sar-layout.h: OMAP4 SAR RAM layout header file
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H
+#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
+
+/*
+ * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE
+ */
+#define SAR_BANK1_OFFSET 0x0000
+#define SAR_BANK2_OFFSET 0x1000
+#define SAR_BANK3_OFFSET 0x2000
+#define SAR_BANK4_OFFSET 0x3000
+
+/* Scratch pad memory offsets from SAR_BANK1 */
+#define CPU0_SAVE_OFFSET 0xb00
+#define CPU1_SAVE_OFFSET 0xc00
+#define MMU_OFFSET0 0xd00
+#define MMU_OFFSET1 0xd10
+#define SCU_OFFSET0 0xd20
+#define SCU_OFFSET1 0xd24
+#define L2X0_OFFSET 0xd28
+#define L2X0_AUXCTRL_OFFSET 0xd2c
+#define L1_OFFSET0 0xd30
+#define L1_OFFSET1 0xd34
+#define OMAP_TYPE_OFFSET 0xd38
+
+/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
+#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
+#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08
+
+/* GIC save restore offset from SAR_BANK3 */
+#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)
+#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)
+#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508)
+#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c)
+#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510)
+#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514)
+#define ICDISER_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x524)
+#define ICDISER_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x528)
+#define ICDISER_SPI_OFFSET (SAR_BANK3_OFFSET + 0x52c)
+#define ICDIPR_SFI_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x53c)
+#define ICDIPR_PPI_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x54c)
+#define ICDIPR_SFI_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x550)
+#define ICDIPR_PPI_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x560)
+#define ICDIPR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x564)
+#define ICDIPTR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x5e4)
+#define ICDICFR_OFFSET (SAR_BANK3_OFFSET + 0x664)
+#define SAR_BACKUP_STATUS_GIC_CPU0 0x1
+#define SAR_BACKUP_STATUS_GIC_CPU1 0x2
+
+/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
+#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
+#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694)
+#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4)
+#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4)
+#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4)
+#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8)
+#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc)
+#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0)
+#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10
+
+#endif
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S
index e69d37d..83ba6d9 100644
--- a/arch/arm/mach-omap2/omap44xx-smc.S
+++ b/arch/arm/mach-omap2/omap44xx-smc.S
@@ -31,6 +31,30 @@ ENTRY(omap_smc1)
ldmfd sp!, {r2-r12, pc}
ENDPROC(omap_smc1)
+/*
+ * Low level common routine to manage secure
+ * HAL APIs.
+ * Function signature : u32 omap_smc2(u32 id, u32 falg, u32 pargs)
+ * @id : Application ID of HAL APIs
+ * @flag : Flag to indicate the criticality of operation
+ * @pargs : Physical address of parameter list starting
+ * with number of parametrs
+ */
+ENTRY(omap_smc2)
+ stmfd sp!, {r1-r12, lr}
+ mov r3, r2
+ mov r2, r1
+ mov r1, #0x0 @ Process ID
+ mov r6, #0xff
+ mov r12, #0x00 @ Secure Service ID
+ mov r7, #0
+ mcr p15, 0, r7, c7, c5, 6
+ dsb
+ dmb
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+END(omap_smc2)
+
ENTRY(omap_modify_auxcoreboot0)
stmfd sp!, {r1-r12, lr}
ldr r12, =0x104
diff --git a/arch/arm/mach-omap2/omap4_trim_quirks.c b/arch/arm/mach-omap2/omap4_trim_quirks.c
new file mode 100644
index 0000000..0ee5bb0
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4_trim_quirks.c
@@ -0,0 +1,78 @@
+/*
+ * OMAP LDO control and configuration
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * 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/kernel.h>
+#include <linux/cpu.h>
+
+#include "control.h"
+
+/**
+ * omap4_ldo_trim_configure() - Handle device trim variance
+ *
+ * Few of the silicon out of the fab come out without trim parameters
+ * efused in. These need some software support to allow the device to
+ * function normally. Handle these silicon quirks here.
+ */
+static int __init omap4_ldo_trim_configure(void)
+{
+ u32 is_trimmed = 0;
+ u32 val;
+
+ /* Applicable only for OMAP4 */
+ if (!cpu_is_omap44xx())
+ return 0;
+
+ /*
+ * Some ES2.2 efuse values for BGAP and SLDO trim
+ * are not programmed. For these units
+ * 1. we can set overide mode for SLDO trim,
+ * and program the max multiplication factor, to ensure
+ * high enough voltage on SLDO output.
+ * 2. trim VDAC value for TV output as per recomendation
+ */
+
+ if (omap_rev() == CHIP_IS_OMAP4430ES2_2)
+ is_trimmed = omap_ctrl_readl(
+ OMAP4_CTRL_MODULE_CORE_LDOSRAM_MPU_VOLTAGE_CTRL);
+
+ /* if not trimmed, we set force overide, insted of efuse. */
+ if (!is_trimmed) {
+ /* Fill in recommended values */
+ val = 0x0f << OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_SHIFT;
+ val |= OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_MASK;
+ val |= 0x1 << OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_SHIFT;
+ val |= OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_MASK;
+
+ omap_ctrl_writel(val,
+ OMAP4_CTRL_MODULE_CORE_LDOSRAM_MPU_VOLTAGE_CTRL);
+ omap_ctrl_writel(val,
+ OMAP4_CTRL_MODULE_CORE_LDOSRAM_CORE_VOLTAGE_CTRL);
+ omap_ctrl_writel(val,
+ OMAP4_CTRL_MODULE_CORE_LDOSRAM_IVA_VOLTAGE_CTRL);
+
+ /* write value as per trim recomendation */
+ val = 0xc0 << OMAP4_AVDAC_TRIM_BYTE0_SHIFT;
+ val |= 0x01 << OMAP4_AVDAC_TRIM_BYTE1_SHIFT;
+ omap_ctrl_writel(val,
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1);
+ }
+
+ /*
+ * For all ESx.y trimmed and untrimmed units LPDDR IO and
+ * Smart IO override efuse.
+ */
+ val = OMAP4_LPDDR2_PTV_P5_MASK | OMAP4_LPDDR2_PTV_N5_MASK;
+ omap_ctrl_writel(val, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2);
+
+ return 0;
+}
+arch_initcall(omap4_ldo_trim_configure);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 293fa6c..94573ef 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -401,7 +401,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
- *v |= wakeup_mask;
+ if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
+ *v |= wakeup_mask;
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
@@ -436,7 +437,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
- *v &= ~wakeup_mask;
+ if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
+ *v &= ~wakeup_mask;
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
@@ -1223,6 +1225,7 @@ static int _reset(struct omap_hwmod *oh)
static int _enable(struct omap_hwmod *oh)
{
int r;
+ int hwsup = 0;
if (oh->_state != _HWMOD_STATE_INITIALIZED &&
oh->_state != _HWMOD_STATE_IDLE &&
@@ -1250,10 +1253,16 @@ static int _enable(struct omap_hwmod *oh)
omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
_add_initiator_dep(oh, mpu_oh);
+ if (oh->_clk && oh->_clk->clkdm) {
+ hwsup = clkdm_is_idle(oh->_clk->clkdm);
+ clkdm_wakeup(oh->_clk->clkdm);
+ }
_enable_clocks(oh);
-
r = _wait_target_ready(oh);
if (!r) {
+ if (oh->_clk && oh->_clk->clkdm && hwsup)
+ clkdm_allow_idle(oh->_clk->clkdm);
+
oh->_state = _HWMOD_STATE_ENABLED;
/* Access the sysconfig only if the target is ready */
@@ -1374,8 +1383,11 @@ static int _shutdown(struct omap_hwmod *oh)
}
}
- if (oh->class->sysc)
+ if (oh->class->sysc) {
+ if (oh->_state == _HWMOD_STATE_IDLE)
+ _enable(oh);
_shutdown_sysc(oh);
+ }
/*
* If an IP contains only one HW reset line, then assert it
@@ -2332,7 +2344,7 @@ ohsps_unlock:
* Returns the context loss count of the powerdomain assocated with @oh
* upon success, or zero if no powerdomain exists for @oh.
*/
-u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
+int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
{
struct powerdomain *pwrdm;
int ret = 0;
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index c4d0ae8..d87019d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -1208,6 +1208,7 @@ static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = {
};
static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss1_fck" },
{ .role = "tv_clk", .clk = "dss_54m_fck" },
{ .role = "sys_clk", .clk = "dss2_fck" },
};
@@ -1291,6 +1292,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = {
&omap2420_l4_core__dss_dispc,
};
+static struct omap_hwmod_opt_clk dispc_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss1_fck" },
+};
+
static struct omap_hwmod omap2420_dss_dispc_hwmod = {
.name = "dss_dispc",
.class = &omap2420_dispc_hwmod_class,
@@ -1306,6 +1311,8 @@ static struct omap_hwmod omap2420_dss_dispc_hwmod = {
.idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
},
},
+ .opt_clks = dispc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dispc_opt_clks),
.slaves = omap2420_dss_dispc_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_dss_dispc_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -1361,6 +1368,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = {
&omap2420_l4_core__dss_rfbi,
};
+static struct omap_hwmod_opt_clk rfbi_opt_clks[] = {
+ { .role = "rfbi_iclk", .clk = "dss_ick" },
+};
+
static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
.name = "dss_rfbi",
.class = &omap2420_rfbi_hwmod_class,
@@ -1372,6 +1383,8 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
.module_offs = CORE_MOD,
},
},
+ .opt_clks = rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(rfbi_opt_clks),
.slaves = omap2420_dss_rfbi_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_dss_rfbi_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -1418,6 +1431,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = {
&omap2420_l4_core__dss_venc,
};
+static struct omap_hwmod_opt_clk venc_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+};
+
static struct omap_hwmod omap2420_dss_venc_hwmod = {
.name = "dss_venc",
.class = &omap2420_venc_hwmod_class,
@@ -1429,6 +1446,8 @@ static struct omap_hwmod omap2420_dss_venc_hwmod = {
.module_offs = CORE_MOD,
},
},
+ .opt_clks = venc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(venc_opt_clks),
.slaves = omap2420_dss_venc_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_dss_venc_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 9682dd5..8009945 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -1302,6 +1302,7 @@ static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = {
};
static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss1_fck" },
{ .role = "tv_clk", .clk = "dss_54m_fck" },
{ .role = "sys_clk", .clk = "dss2_fck" },
};
@@ -1379,6 +1380,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = {
&omap2430_l4_core__dss_dispc,
};
+static struct omap_hwmod_opt_clk dispc_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss1_fck" },
+};
+
static struct omap_hwmod omap2430_dss_dispc_hwmod = {
.name = "dss_dispc",
.class = &omap2430_dispc_hwmod_class,
@@ -1394,6 +1399,8 @@ static struct omap_hwmod omap2430_dss_dispc_hwmod = {
.idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
},
},
+ .opt_clks = dispc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dispc_opt_clks),
.slaves = omap2430_dss_dispc_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_dss_dispc_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -1443,6 +1450,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = {
&omap2430_l4_core__dss_rfbi,
};
+static struct omap_hwmod_opt_clk rfbi_opt_clks[] = {
+ { .role = "rfbi_iclk", .clk = "dss_ick" },
+};
+
static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
.name = "dss_rfbi",
.class = &omap2430_rfbi_hwmod_class,
@@ -1454,6 +1465,8 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
.module_offs = CORE_MOD,
},
},
+ .opt_clks = rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(rfbi_opt_clks),
.slaves = omap2430_dss_rfbi_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_dss_rfbi_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -1494,6 +1507,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = {
&omap2430_l4_core__dss_venc,
};
+static struct omap_hwmod_opt_clk venc_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+};
+
static struct omap_hwmod omap2430_dss_venc_hwmod = {
.name = "dss_venc",
.class = &omap2430_venc_hwmod_class,
@@ -1505,6 +1522,8 @@ static struct omap_hwmod omap2430_dss_venc_hwmod = {
.module_offs = CORE_MOD,
},
},
+ .opt_clks = venc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(venc_opt_clks),
.slaves = omap2430_dss_venc_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_dss_venc_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 909a84d..3dad446 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -29,6 +29,7 @@
#include "omap_hwmod_common_data.h"
+#include "smartreflex.h"
#include "prm-regbits-34xx.h"
#include "cm-regbits-34xx.h"
#include "wd_timer.h"
@@ -1542,9 +1543,15 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
};
static struct omap_hwmod_opt_clk dss_opt_clks[] = {
- { .role = "tv_clk", .clk = "dss_tv_fck" },
- { .role = "video_clk", .clk = "dss_96m_fck" },
+ { .role = "dss_clk", .clk = "dss1_alwon_fck" },
+ /*
+ * The rest of the clocks are not needed by the driver,
+ * but are needed by the hwmod to reset DSS properly.
+ */
{ .role = "sys_clk", .clk = "dss2_alwon_fck" },
+ { .role = "tv_clk", .clk = "dss_tv_fck" },
+ /* required only on OMAP3430 */
+ { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
};
static struct omap_hwmod omap3430es1_dss_core_hwmod = {
@@ -1656,6 +1663,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
&omap3xxx_l4_core__dss_dispc,
};
+static struct omap_hwmod_opt_clk dispc_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss1_alwon_fck" },
+};
+
static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
.name = "dss_dispc",
.class = &omap3xxx_dispc_hwmod_class,
@@ -1669,6 +1680,8 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
.module_offs = OMAP3430_DSS_MOD,
},
},
+ .opt_clks = dispc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dispc_opt_clks),
.slaves = omap3xxx_dss_dispc_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
@@ -1720,6 +1733,11 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
&omap3xxx_l4_core__dss_dsi1,
};
+static struct omap_hwmod_opt_clk dsi1_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss1_alwon_fck" },
+ { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+};
+
static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
.name = "dss_dsi1",
.class = &omap3xxx_dsi_hwmod_class,
@@ -1733,6 +1751,8 @@ static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
.module_offs = OMAP3430_DSS_MOD,
},
},
+ .opt_clks = dsi1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dsi1_opt_clks),
.slaves = omap3xxx_dss_dsi1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
@@ -1791,6 +1811,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = {
&omap3xxx_l4_core__dss_rfbi,
};
+static struct omap_hwmod_opt_clk rfbi_opt_clks[] = {
+ { .role = "rfbi_iclk", .clk = "dss_ick" },
+};
+
static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
.name = "dss_rfbi",
.class = &omap3xxx_rfbi_hwmod_class,
@@ -1802,6 +1826,8 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
.module_offs = OMAP3430_DSS_MOD,
},
},
+ .opt_clks = rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(rfbi_opt_clks),
.slaves = omap3xxx_dss_rfbi_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
@@ -1851,6 +1877,12 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = {
&omap3xxx_l4_core__dss_venc,
};
+static struct omap_hwmod_opt_clk venc_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_tv_fck" },
+ /* required only on OMAP3430 */
+ { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
+};
+
static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
.name = "dss_venc",
.class = &omap3xxx_venc_hwmod_class,
@@ -1862,6 +1894,8 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
.module_offs = OMAP3430_DSS_MOD,
},
},
+ .opt_clks = venc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(venc_opt_clks),
.slaves = omap3xxx_dss_venc_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_dss_venc_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
@@ -2910,6 +2944,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
};
/* SR1 */
+static struct omap_smartreflex_dev_attr sr1_dev_attr = {
+ .sensor_voltdm_name = "mpu_iva",
+};
+
static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = {
&omap3_l4_core__sr1,
};
@@ -2918,7 +2956,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
.name = "sr1_hwmod",
.class = &omap34xx_smartreflex_hwmod_class,
.main_clk = "sr1_fck",
- .vdd_name = "mpu",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
@@ -2930,6 +2967,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
},
.slaves = omap3_sr1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
+ .dev_attr = &sr1_dev_attr,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
CHIP_IS_OMAP3430ES3_0 |
CHIP_IS_OMAP3430ES3_1),
@@ -2940,7 +2978,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
.name = "sr1_hwmod",
.class = &omap36xx_smartreflex_hwmod_class,
.main_clk = "sr1_fck",
- .vdd_name = "mpu",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
@@ -2952,10 +2989,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
},
.slaves = omap3_sr1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
+ .dev_attr = &sr1_dev_attr,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
};
/* SR2 */
+static struct omap_smartreflex_dev_attr sr2_dev_attr = {
+ .sensor_voltdm_name = "core",
+};
+
static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = {
&omap3_l4_core__sr2,
};
@@ -2964,7 +3006,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
.name = "sr2_hwmod",
.class = &omap34xx_smartreflex_hwmod_class,
.main_clk = "sr2_fck",
- .vdd_name = "core",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
@@ -2976,6 +3017,7 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
},
.slaves = omap3_sr2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
+ .dev_attr = &sr2_dev_attr,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
CHIP_IS_OMAP3430ES3_0 |
CHIP_IS_OMAP3430ES3_1),
@@ -2986,7 +3028,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
.name = "sr2_hwmod",
.class = &omap36xx_smartreflex_hwmod_class,
.main_clk = "sr2_fck",
- .vdd_name = "core",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
@@ -2998,6 +3039,7 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
},
.slaves = omap3_sr2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
+ .dev_attr = &sr2_dev_attr,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index f5158fe..196b276 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,6 +30,7 @@
#include "omap_hwmod_common_data.h"
+#include "smartreflex.h"
#include "cm1_44xx.h"
#include "cm2_44xx.h"
#include "prm44xx.h"
@@ -49,6 +50,8 @@ static struct omap_hwmod omap44xx_dmm_hwmod;
static struct omap_hwmod omap44xx_dsp_hwmod;
static struct omap_hwmod omap44xx_dss_hwmod;
static struct omap_hwmod omap44xx_emif_fw_hwmod;
+static struct omap_hwmod omap44xx_fdif_hwmod;
+static struct omap_hwmod omap44xx_gpu_hwmod;
static struct omap_hwmod omap44xx_hsi_hwmod;
static struct omap_hwmod omap44xx_ipu_hwmod;
static struct omap_hwmod omap44xx_iss_hwmod;
@@ -65,6 +68,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod;
static struct omap_hwmod omap44xx_mmc2_hwmod;
static struct omap_hwmod omap44xx_mpu_hwmod;
static struct omap_hwmod omap44xx_mpu_private_hwmod;
+static struct omap_hwmod omap44xx_sl2if_hwmod;
static struct omap_hwmod omap44xx_usb_otg_hs_hwmod;
/*
@@ -124,7 +128,7 @@ static struct omap_hwmod omap44xx_dmm_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
.mpu_irqs = omap44xx_dmm_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -173,7 +177,7 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = {
.class = &omap44xx_emif_fw_hwmod_class,
.slaves = omap44xx_emif_fw_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -212,7 +216,7 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.class = &omap44xx_l3_hwmod_class,
.slaves = omap44xx_l3_instr_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* l3_main_1 interface data */
@@ -306,7 +310,7 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_l3_targ_irqs),
.slaves = omap44xx_l3_main_1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* l3_main_2 interface data */
@@ -318,6 +322,14 @@ static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* gpu -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_gpu__l3_main_2 = {
+ .master = &omap44xx_gpu_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* hsi -> l3_main_2 */
static struct omap_hwmod_ocp_if omap44xx_hsi__l3_main_2 = {
.master = &omap44xx_hsi_hwmod,
@@ -342,6 +354,14 @@ static struct omap_hwmod_ocp_if omap44xx_iss__l3_main_2 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* fdif -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_fdif__l3_main_2 = {
+ .master = &omap44xx_fdif_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* iva -> l3_main_2 */
static struct omap_hwmod_ocp_if omap44xx_iva__l3_main_2 = {
.master = &omap44xx_iva_hwmod,
@@ -390,8 +410,10 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
&omap44xx_hsi__l3_main_2,
&omap44xx_ipu__l3_main_2,
&omap44xx_iss__l3_main_2,
+ &omap44xx_fdif__l3_main_2,
&omap44xx_iva__l3_main_2,
&omap44xx_l3_main_1__l3_main_2,
+ &omap44xx_gpu__l3_main_2,
&omap44xx_l4_cfg__l3_main_2,
&omap44xx_usb_otg_hs__l3_main_2,
};
@@ -401,7 +423,7 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
.class = &omap44xx_l3_hwmod_class,
.slaves = omap44xx_l3_main_2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* l3_main_3 interface data */
@@ -451,7 +473,7 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
.class = &omap44xx_l3_hwmod_class,
.slaves = omap44xx_l3_main_3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -508,7 +530,7 @@ static struct omap_hwmod omap44xx_l4_abe_hwmod = {
.class = &omap44xx_l4_hwmod_class,
.slaves = omap44xx_l4_abe_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* l4_cfg interface data */
@@ -530,7 +552,7 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
.class = &omap44xx_l4_hwmod_class,
.slaves = omap44xx_l4_cfg_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* l4_per interface data */
@@ -552,7 +574,7 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = {
.class = &omap44xx_l4_hwmod_class,
.slaves = omap44xx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* l4_wkup interface data */
@@ -574,7 +596,7 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
.class = &omap44xx_l4_hwmod_class,
.slaves = omap44xx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -604,7 +626,7 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
.class = &omap44xx_mpu_bus_hwmod_class,
.slaves = omap44xx_mpu_private_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -629,7 +651,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
* elm
* emif1
* emif2
- * fdif
* gpmc
* gpu
* hdq1w
@@ -640,7 +661,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
* prcm_mpu
* prm
* scrm
- * sl2if
* slimbus1
* slimbus2
* usb_host_fs
@@ -651,6 +671,222 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
*/
/*
+ * 'mpu' class
+ * mpu sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
+ { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
+ { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
+ { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* mpu master ports */
+static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = {
+ &omap44xx_mpu__l3_main_1,
+ &omap44xx_mpu__l4_abe,
+ &omap44xx_mpu__dmm,
+};
+
+static struct omap_hwmod omap44xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &omap44xx_mpu_hwmod_class,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+ .mpu_irqs = omap44xx_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
+ },
+ },
+ .masters = omap44xx_mpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/*
+ * 'smartreflex' class
+ * smartreflex module (monitor silicon performance and outputs a measure of
+ * performance error)
+ */
+
+/* The IP is not compliant to type1 / type2 scheme */
+static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = {
+ .sidle_shift = 24,
+ .enwkup_shift = 26,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
+ .sysc_offs = 0x0038,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type_smartreflex,
+};
+
+static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap44xx_smartreflex_sysc,
+ .rev = 2,
+};
+
+/* smartreflex_core */
+static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = {
+ .sensor_voltdm_name = "core",
+};
+
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
+ { .irq = 19 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = {
+ {
+ .pa_start = 0x4a0dd000,
+ .pa_end = 0x4a0dd03f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_core_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_core slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_core,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
+ .name = "smartreflex_core",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_core_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
+ .main_clk = "smartreflex_core_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
+ .dev_attr = &smartreflex_core_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/* smartreflex_iva */
+static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = {
+ .sensor_voltdm_name = "iva",
+};
+
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
+ { .irq = 102 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = {
+ {
+ .pa_start = 0x4a0db000,
+ .pa_end = 0x4a0db03f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_iva */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_iva_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_iva_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_iva slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_iva,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
+ .name = "smartreflex_iva",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_iva_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
+ .main_clk = "smartreflex_iva_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_iva_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
+ .dev_attr = &smartreflex_iva_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/* smartreflex_mpu */
+static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
+ .sensor_voltdm_name = "mpu",
+};
+
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
+ { .irq = 18 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = {
+ {
+ .pa_start = 0x4a0d9000,
+ .pa_end = 0x4a0d903f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_mpu */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_mpu_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_mpu_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_mpu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_mpu,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
+ .name = "smartreflex_mpu",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
+ .main_clk = "smartreflex_mpu_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_mpu_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
+ .dev_attr = &smartreflex_mpu_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/*
* 'aess' class
* audio engine sub system
*/
@@ -658,7 +894,7 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
- .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+ .sysc_flags = 0,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
.sysc_fields = &omap_hwmod_sysc_type2,
@@ -692,6 +928,27 @@ static struct omap_hwmod_ocp_if *omap44xx_aess_masters[] = {
static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = {
{
+ .name = "dmem",
+ .pa_start = 0x40180000,
+ .pa_end = 0x4018ffff
+ },
+ {
+ .name = "cmem",
+ .pa_start = 0x401a0000,
+ .pa_end = 0x401a1fff
+ },
+ {
+ .name = "smem",
+ .pa_start = 0x401c0000,
+ .pa_end = 0x401c5fff
+ },
+ {
+ .name = "pmem",
+ .pa_start = 0x401e0000,
+ .pa_end = 0x401e1fff
+ },
+ {
+ .name = "mpu",
.pa_start = 0x401f1000,
.pa_end = 0x401f13ff,
.flags = ADDR_TYPE_RT
@@ -710,6 +967,27 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess = {
static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = {
{
+ .name = "dmem_dma",
+ .pa_start = 0x49080000,
+ .pa_end = 0x4908ffff
+ },
+ {
+ .name = "cmem_dma",
+ .pa_start = 0x490a0000,
+ .pa_end = 0x490a1fff
+ },
+ {
+ .name = "smem_dma",
+ .pa_start = 0x490c0000,
+ .pa_end = 0x490c5fff
+ },
+ {
+ .name = "pmem_dma",
+ .pa_start = 0x490e0000,
+ .pa_end = 0x490e1fff
+ },
+ {
+ .name = "dma",
.pa_start = 0x490f1000,
.pa_end = 0x490f13ff,
.flags = ADDR_TYPE_RT
@@ -749,7 +1027,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_aess_slaves),
.masters = omap44xx_aess_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_aess_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -762,11 +1040,28 @@ static struct omap_hwmod_class omap44xx_bandgap_hwmod_class = {
};
/* bandgap */
-static struct omap_hwmod_opt_clk bandgap_opt_clks[] = {
+static struct omap_hwmod_opt_clk bandgap443x_opt_clks[] = {
{ .role = "fclk", .clk = "bandgap_fclk" },
};
-static struct omap_hwmod omap44xx_bandgap_hwmod = {
+static struct omap_hwmod omap443x_bandgap_hwmod = {
+ .name = "bandgap",
+ .class = &omap44xx_bandgap_hwmod_class,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ },
+ },
+ .opt_clks = bandgap443x_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(bandgap443x_opt_clks),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP443X),
+};
+
+static struct omap_hwmod_opt_clk bandgap446x_opt_clks[] = {
+ { .role = "fclk", .clk = "bandgap_ts_fclk" },
+};
+
+static struct omap_hwmod omap446x_bandgap_hwmod = {
.name = "bandgap",
.class = &omap44xx_bandgap_hwmod_class,
.prcm = {
@@ -774,9 +1069,9 @@ static struct omap_hwmod omap44xx_bandgap_hwmod = {
.clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
},
},
- .opt_clks = bandgap_opt_clks,
- .opt_clks_cnt = ARRAY_SIZE(bandgap_opt_clks),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .opt_clks = bandgap446x_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(bandgap446x_opt_clks),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
};
/*
@@ -835,7 +1130,7 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = {
},
.slaves = omap44xx_counter_32k_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_counter_32k_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -921,7 +1216,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_dma_system_slaves),
.masters = omap44xx_dma_system_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_dma_system_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1011,7 +1306,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {
},
.slaves = omap44xx_dmic_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dmic_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1051,11 +1346,19 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {
.clk = "dpll_iva_m5x2_ck",
};
+/* dsp -> sl2if */
+static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_sl2if_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+};
+
/* dsp master ports */
static struct omap_hwmod_ocp_if *omap44xx_dsp_masters[] = {
&omap44xx_dsp__l3_main_1,
&omap44xx_dsp__l4_abe,
&omap44xx_dsp__iva,
+ &omap44xx_dsp__sl2if,
};
/* l4_cfg -> dsp */
@@ -1085,12 +1388,13 @@ static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
.rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct omap_hwmod omap44xx_dsp_hwmod = {
.name = "dsp",
.class = &omap44xx_dsp_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_dsp_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dsp_irqs),
.rst_lines = omap44xx_dsp_resets,
@@ -1106,7 +1410,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_dsp_slaves),
.masters = omap44xx_dsp_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_dsp_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1120,9 +1424,16 @@ static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = {
.sysc_flags = SYSS_HAS_RESET_STATUS,
};
+static int omap44xx_dss_reset(struct omap_hwmod *oh)
+{
+ omap_hwmod_write(0x0, oh, 0x40);
+ return 0;
+}
+
static struct omap_hwmod_class omap44xx_dss_hwmod_class = {
.name = "dss",
.sysc = &omap44xx_dss_sysc,
+ .reset = omap44xx_dss_reset,
};
/* dss */
@@ -1174,10 +1485,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = {
};
static struct omap_hwmod_opt_clk dss_opt_clks[] = {
- { .role = "sys_clk", .clk = "dss_sys_clk" },
- { .role = "tv_clk", .clk = "dss_tv_clk" },
{ .role = "dss_clk", .clk = "dss_dss_clk" },
- { .role = "video_clk", .clk = "dss_48mhz_clk" },
};
static struct omap_hwmod omap44xx_dss_hwmod = {
@@ -1195,7 +1503,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_slaves),
.masters = omap44xx_dss_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_dss_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1273,9 +1581,21 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = {
&omap44xx_l4_per__dss_dispc,
};
+static struct omap_hwmod_opt_clk dispc_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss_dss_clk" },
+ /*
+ * The rest of the clocks are not needed by the driver,
+ * but are needed by the hwmod to reset DSS properly.
+ */
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+ { .role = "tv_clk", .clk = "dss_tv_clk" },
+ { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
+};
+
static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.name = "dss_dispc",
.class = &omap44xx_dispc_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
.mpu_irqs = omap44xx_dss_dispc_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_irqs),
.sdma_reqs = omap44xx_dss_dispc_sdma_reqs,
@@ -1286,9 +1606,11 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
},
},
+ .opt_clks = dispc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dispc_opt_clks),
.slaves = omap44xx_dss_dispc_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1364,6 +1686,11 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = {
&omap44xx_l4_per__dss_dsi1,
};
+static struct omap_hwmod_opt_clk dsi1_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss_dss_clk" },
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.name = "dss_dsi1",
.class = &omap44xx_dsi_hwmod_class,
@@ -1377,9 +1704,11 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
},
},
+ .opt_clks = dsi1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dsi1_opt_clks),
.slaves = omap44xx_dss_dsi1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* dss_dsi2 */
@@ -1449,7 +1778,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
},
.slaves = omap44xx_dss_dsi2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1524,6 +1853,11 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = {
&omap44xx_l4_per__dss_hdmi,
};
+static struct omap_hwmod_opt_clk hdmi_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+ { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
+};
+
static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
.name = "dss_hdmi",
.class = &omap44xx_hdmi_hwmod_class,
@@ -1537,9 +1871,11 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
.clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
},
},
+ .opt_clks = hdmi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(hdmi_opt_clks),
.slaves = omap44xx_dss_hdmi_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1610,6 +1946,10 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = {
&omap44xx_l4_per__dss_rfbi,
};
+static struct omap_hwmod_opt_clk rfbi_opt_clks[] = {
+ { .role = "rfbi_iclk", .clk = "dss_fck" },
+};
+
static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
.name = "dss_rfbi",
.class = &omap44xx_rfbi_hwmod_class,
@@ -1621,9 +1961,11 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
.clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
},
},
+ .opt_clks = rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(rfbi_opt_clks),
.slaves = omap44xx_dss_rfbi_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1679,6 +2021,10 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = {
&omap44xx_l4_per__dss_venc,
};
+static struct omap_hwmod_opt_clk venc_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_tv_clk" },
+};
+
static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.name = "dss_venc",
.class = &omap44xx_venc_hwmod_class,
@@ -1688,9 +2034,82 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
},
},
+ .opt_clks = venc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(venc_opt_clks),
.slaves = omap44xx_dss_venc_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_venc_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/*
+ * 'fdif' class
+ * face detection hw accelerator module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_fdif_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_fdif_hwmod_class = {
+ .name = "fdif",
+ .sysc = &omap44xx_fdif_sysc,
+};
+
+/* fdif */
+static struct omap_hwmod_irq_info omap44xx_fdif_irqs[] = {
+ { .irq = 69 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* fdif master ports */
+static struct omap_hwmod_ocp_if *omap44xx_fdif_masters[] = {
+ &omap44xx_fdif__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_fdif_addrs[] = {
+ {
+ .pa_start = 0x4a10a000,
+ .pa_end = 0x4a10a1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> fdif */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__fdif = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_fdif_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_fdif_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_fdif_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* fdif slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_fdif_slaves[] = {
+ &omap44xx_l3_main_2__fdif,
+};
+
+static struct omap_hwmod omap44xx_fdif_hwmod = {
+ .name = "fdif",
+ .class = &omap44xx_fdif_hwmod_class,
+ .mpu_irqs = omap44xx_fdif_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_fdif_irqs),
+ .main_clk = "fdif_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_CAM_FDIF_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_fdif_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_fdif_slaves),
+ .masters = omap44xx_fdif_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_fdif_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -1755,7 +2174,7 @@ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
{ .role = "dbclk", .clk = "gpio1_dbclk" },
};
-static struct omap_hwmod omap44xx_gpio1_hwmod = {
+static struct omap_hwmod omap443x_gpio1_hwmod = {
.name = "gpio1",
.class = &omap44xx_gpio_hwmod_class,
.mpu_irqs = omap44xx_gpio1_irqs,
@@ -1771,7 +2190,27 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP443X),
+};
+
+static struct omap_hwmod omap446x_gpio1_hwmod = {
+ .name = "gpio1",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio1_irqs),
+ .main_clk = "gpio1_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
};
/* gpio2 */
@@ -1810,7 +2249,8 @@ static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio2_hwmod = {
.name = "gpio2",
.class = &omap44xx_gpio_hwmod_class,
- .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET |
+ HWMOD_SWSUP_SIDLE ,
.mpu_irqs = omap44xx_gpio2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio2_irqs),
.main_clk = "gpio2_ick",
@@ -1824,7 +2264,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* gpio3 */
@@ -1877,7 +2317,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* gpio4 */
@@ -1930,7 +2370,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* gpio5 */
@@ -1983,7 +2423,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio5_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* gpio6 */
@@ -2036,7 +2476,44 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio6_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/*
+ * 'gpu' class
+ * 2d/3d graphics accelerator
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_gpu_sysc = {
+ .rev_offs = 0xfe00,
+ .sysc_offs = 0xfe10,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_gpu_hwmod_class = {
+ .name = "gpu",
+ .sysc = &omap44xx_gpu_sysc,
+};
+
+/* gpu */
+static struct omap_hwmod_irq_info omap44xx_gpu_irqs[] = {
+ { .irq = 21 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* gpu master ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpu_masters[] = {
+ &omap44xx_gpu__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpu_addrs[] = {
+ {
+ .pa_start = 0x56000000,
+ .pa_end = 0x5600ffff,
+ .flags = ADDR_TYPE_RT
+ },
};
/*
@@ -2113,7 +2590,41 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_hsi_slaves),
.masters = omap44xx_hsi_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_hsi_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/* l3_main_2 -> gpu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpu = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_gpu_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_gpu_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpu_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpu_slaves[] = {
+ &omap44xx_l3_main_2__gpu,
+};
+
+static struct omap_hwmod omap44xx_gpu_hwmod = {
+ .name = "gpu",
+ .class = &omap44xx_gpu_hwmod_class,
+ .mpu_irqs = omap44xx_gpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpu_irqs),
+ .main_clk = "gpu_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_gpu_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpu_slaves),
+ .masters = omap44xx_gpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_gpu_masters),
+ .dev_attr = &smartreflex_core_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2187,7 +2698,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
},
.slaves = omap44xx_i2c1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* i2c2 */
@@ -2240,7 +2751,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
},
.slaves = omap44xx_i2c2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* i2c3 */
@@ -2293,7 +2804,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
},
.slaves = omap44xx_i2c3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* i2c4 */
@@ -2346,7 +2857,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
},
.slaves = omap44xx_i2c4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2415,7 +2926,7 @@ static struct omap_hwmod omap44xx_ipu_c0_hwmod = {
.rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* Pseudo hwmod for reset control purpose only */
@@ -2430,7 +2941,7 @@ static struct omap_hwmod omap44xx_ipu_c1_hwmod = {
.rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct omap_hwmod omap44xx_ipu_hwmod = {
@@ -2452,7 +2963,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_ipu_slaves),
.masters = omap44xx_ipu_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_ipu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2539,7 +3050,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_iss_slaves),
.masters = omap44xx_iss_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_iss_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2570,8 +3081,16 @@ static struct omap_hwmod_rst_info omap44xx_iva_seq1_resets[] = {
{ .name = "seq1", .rst_shift = 1 },
};
+/* iva -> sl2if */
+static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = {
+ .master = &omap44xx_iva_hwmod,
+ .slave = &omap44xx_sl2if_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+};
+
/* iva master ports */
static struct omap_hwmod_ocp_if *omap44xx_iva_masters[] = {
+ &omap44xx_iva__sl2if,
&omap44xx_iva__l3_main_2,
&omap44xx_iva__l3_instr,
};
@@ -2612,7 +3131,7 @@ static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
.rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* Pseudo hwmod for reset control purpose only */
@@ -2627,7 +3146,7 @@ static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
.rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static struct omap_hwmod omap44xx_iva_hwmod = {
@@ -2648,7 +3167,46 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_iva_slaves),
.masters = omap44xx_iva_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_iva_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+};
+
+/*
+ * 'sl2if' class
+ * shared level 2 memory interface
+ */
+
+static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = {
+ .name = "sl2if",
+};
+
+/* sl2if */
+/* l3_main_2 -> sl2if */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_sl2if_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* sl2if slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_sl2if_slaves[] = {
+ &omap44xx_l3_main_2__sl2if,
+ &omap44xx_iva__sl2if,
+ &omap44xx_dsp__sl2if,
+};
+
+static struct omap_hwmod omap44xx_sl2if_hwmod = {
+ .name = "sl2if",
+ .class = &omap44xx_sl2if_hwmod_class,
+ .main_clk = "sl2if_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_IVAHD_SL2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_sl2if_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_sl2if_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2715,7 +3273,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
},
.slaves = omap44xx_kbd_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_kbd_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2779,7 +3337,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {
},
.slaves = omap44xx_mailbox_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mailbox_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -2804,7 +3362,8 @@ static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
/* mcbsp1 */
static struct omap_hwmod omap44xx_mcbsp1_hwmod;
static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = {
- { .irq = 17 + OMAP44XX_IRQ_GIC_START },
+ { .name = "tx", .irq = 17 + OMAP44XX_IRQ_GIC_START },
+ { .name = "rx", .irq = 0 },
};
static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = {
@@ -2871,13 +3430,14 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
},
.slaves = omap44xx_mcbsp1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mcbsp2 */
static struct omap_hwmod omap44xx_mcbsp2_hwmod;
static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = {
- { .irq = 22 + OMAP44XX_IRQ_GIC_START },
+ { .name = "tx", .irq = 22 + OMAP44XX_IRQ_GIC_START },
+ { .name = "rx", .irq = 0 },
};
static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = {
@@ -2944,13 +3504,14 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
},
.slaves = omap44xx_mcbsp2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mcbsp3 */
static struct omap_hwmod omap44xx_mcbsp3_hwmod;
static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = {
- { .irq = 23 + OMAP44XX_IRQ_GIC_START },
+ { .name = "tx", .irq = 23 + OMAP44XX_IRQ_GIC_START },
+ { .name = "rx", .irq = 0 },
};
static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = {
@@ -3017,13 +3578,14 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
},
.slaves = omap44xx_mcbsp3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mcbsp4 */
static struct omap_hwmod omap44xx_mcbsp4_hwmod;
static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = {
- { .irq = 16 + OMAP44XX_IRQ_GIC_START },
+ { .name = "tx", .irq = 16 + OMAP44XX_IRQ_GIC_START },
+ { .name = "rx", .irq = 0 },
};
static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = {
@@ -3069,7 +3631,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
},
.slaves = omap44xx_mcbsp4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -3161,7 +3723,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
},
.slaves = omap44xx_mcpdm_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcpdm_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -3247,7 +3809,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
.dev_attr = &mcspi1_dev_attr,
.slaves = omap44xx_mcspi1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mcspi2 */
@@ -3307,7 +3869,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
.dev_attr = &mcspi2_dev_attr,
.slaves = omap44xx_mcspi2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mcspi3 */
@@ -3367,7 +3929,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
.dev_attr = &mcspi3_dev_attr,
.slaves = omap44xx_mcspi3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mcspi4 */
@@ -3425,7 +3987,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
.dev_attr = &mcspi4_dev_attr,
.slaves = omap44xx_mcspi4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -3512,7 +4074,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc1_slaves),
.masters = omap44xx_mmc1_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_mmc1_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mmc2 */
@@ -3570,7 +4132,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc2_slaves),
.masters = omap44xx_mmc2_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_mmc2_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mmc3 */
@@ -3622,7 +4184,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {
},
.slaves = omap44xx_mmc3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mmc4 */
@@ -3674,7 +4236,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {
},
.slaves = omap44xx_mmc4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* mmc5 */
@@ -3726,211 +4288,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
},
.slaves = omap44xx_mmc5_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-};
-
-/*
- * 'mpu' class
- * mpu sub-system
- */
-
-static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
- .name = "mpu",
-};
-
-/* mpu */
-static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
- { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
- { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
- { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
-};
-
-/* mpu master ports */
-static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = {
- &omap44xx_mpu__l3_main_1,
- &omap44xx_mpu__l4_abe,
- &omap44xx_mpu__dmm,
-};
-
-static struct omap_hwmod omap44xx_mpu_hwmod = {
- .name = "mpu",
- .class = &omap44xx_mpu_hwmod_class,
- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
- .mpu_irqs = omap44xx_mpu_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
- .main_clk = "dpll_mpu_m2_ck",
- .prcm = {
- .omap4 = {
- .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
- },
- },
- .masters = omap44xx_mpu_masters,
- .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-};
-
-/*
- * 'smartreflex' class
- * smartreflex module (monitor silicon performance and outputs a measure of
- * performance error)
- */
-
-/* The IP is not compliant to type1 / type2 scheme */
-static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = {
- .sidle_shift = 24,
- .enwkup_shift = 26,
-};
-
-static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
- .sysc_offs = 0x0038,
- .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
- SIDLE_SMART_WKUP),
- .sysc_fields = &omap_hwmod_sysc_type_smartreflex,
-};
-
-static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
- .name = "smartreflex",
- .sysc = &omap44xx_smartreflex_sysc,
- .rev = 2,
-};
-
-/* smartreflex_core */
-static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
-static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
- { .irq = 19 + OMAP44XX_IRQ_GIC_START },
-};
-
-static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = {
- {
- .pa_start = 0x4a0dd000,
- .pa_end = 0x4a0dd03f,
- .flags = ADDR_TYPE_RT
- },
-};
-
-/* l4_cfg -> smartreflex_core */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
- .master = &omap44xx_l4_cfg_hwmod,
- .slave = &omap44xx_smartreflex_core_hwmod,
- .clk = "l4_div_ck",
- .addr = omap44xx_smartreflex_core_addrs,
- .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs),
- .user = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* smartreflex_core slave ports */
-static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
- &omap44xx_l4_cfg__smartreflex_core,
-};
-
-static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
- .name = "smartreflex_core",
- .class = &omap44xx_smartreflex_hwmod_class,
- .mpu_irqs = omap44xx_smartreflex_core_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
- .main_clk = "smartreflex_core_fck",
- .vdd_name = "core",
- .prcm = {
- .omap4 = {
- .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
- },
- },
- .slaves = omap44xx_smartreflex_core_slaves,
- .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-};
-
-/* smartreflex_iva */
-static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
-static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
- { .irq = 102 + OMAP44XX_IRQ_GIC_START },
-};
-
-static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = {
- {
- .pa_start = 0x4a0db000,
- .pa_end = 0x4a0db03f,
- .flags = ADDR_TYPE_RT
- },
-};
-
-/* l4_cfg -> smartreflex_iva */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
- .master = &omap44xx_l4_cfg_hwmod,
- .slave = &omap44xx_smartreflex_iva_hwmod,
- .clk = "l4_div_ck",
- .addr = omap44xx_smartreflex_iva_addrs,
- .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs),
- .user = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* smartreflex_iva slave ports */
-static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
- &omap44xx_l4_cfg__smartreflex_iva,
-};
-
-static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
- .name = "smartreflex_iva",
- .class = &omap44xx_smartreflex_hwmod_class,
- .mpu_irqs = omap44xx_smartreflex_iva_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
- .main_clk = "smartreflex_iva_fck",
- .vdd_name = "iva",
- .prcm = {
- .omap4 = {
- .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
- },
- },
- .slaves = omap44xx_smartreflex_iva_slaves,
- .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-};
-
-/* smartreflex_mpu */
-static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
-static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
- { .irq = 18 + OMAP44XX_IRQ_GIC_START },
-};
-
-static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = {
- {
- .pa_start = 0x4a0d9000,
- .pa_end = 0x4a0d903f,
- .flags = ADDR_TYPE_RT
- },
-};
-
-/* l4_cfg -> smartreflex_mpu */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
- .master = &omap44xx_l4_cfg_hwmod,
- .slave = &omap44xx_smartreflex_mpu_hwmod,
- .clk = "l4_div_ck",
- .addr = omap44xx_smartreflex_mpu_addrs,
- .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs),
- .user = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* smartreflex_mpu slave ports */
-static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
- &omap44xx_l4_cfg__smartreflex_mpu,
-};
-
-static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
- .name = "smartreflex_mpu",
- .class = &omap44xx_smartreflex_hwmod_class,
- .mpu_irqs = omap44xx_smartreflex_mpu_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
- .main_clk = "smartreflex_mpu_fck",
- .vdd_name = "mpu",
- .prcm = {
- .omap4 = {
- .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
- },
- },
- .slaves = omap44xx_smartreflex_mpu_slaves,
- .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -3991,7 +4349,7 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = {
},
.slaves = omap44xx_spinlock_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_spinlock_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -4074,7 +4432,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
},
.slaves = omap44xx_timer1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer2 */
@@ -4119,7 +4477,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
},
.slaves = omap44xx_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer3 */
@@ -4164,7 +4522,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
},
.slaves = omap44xx_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer4 */
@@ -4209,7 +4567,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
},
.slaves = omap44xx_timer4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer5 */
@@ -4273,7 +4631,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
},
.slaves = omap44xx_timer5_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer6 */
@@ -4337,7 +4695,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
},
.slaves = omap44xx_timer6_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer6_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer7 */
@@ -4401,7 +4759,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
},
.slaves = omap44xx_timer7_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer7_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer8 */
@@ -4465,7 +4823,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
},
.slaves = omap44xx_timer8_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer8_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer9 */
@@ -4510,7 +4868,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
},
.slaves = omap44xx_timer9_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer9_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer10 */
@@ -4555,7 +4913,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
},
.slaves = omap44xx_timer10_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer10_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* timer11 */
@@ -4600,7 +4958,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
},
.slaves = omap44xx_timer11_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer11_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -4674,7 +5032,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
},
.slaves = omap44xx_uart1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* uart2 */
@@ -4726,7 +5084,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
},
.slaves = omap44xx_uart2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* uart3 */
@@ -4779,7 +5137,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
},
.slaves = omap44xx_uart3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* uart4 */
@@ -4831,7 +5189,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
},
.slaves = omap44xx_uart4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -4913,7 +5271,7 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_slaves),
.masters = omap44xx_usb_otg_hs_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/*
@@ -4981,7 +5339,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
},
.slaves = omap44xx_wd_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
/* wd_timer3 */
@@ -5045,7 +5403,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
},
.slaves = omap44xx_wd_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};
static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
@@ -5072,10 +5430,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&omap44xx_mpu_private_hwmod,
/* aess class */
-/* &omap44xx_aess_hwmod, */
+ &omap44xx_aess_hwmod,
/* bandgap class */
- &omap44xx_bandgap_hwmod,
+ &omap443x_bandgap_hwmod,
+ &omap446x_bandgap_hwmod,
/* counter class */
/* &omap44xx_counter_32k_hwmod, */
@@ -5100,7 +5459,8 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&omap44xx_dss_venc_hwmod,
/* gpio class */
- &omap44xx_gpio1_hwmod,
+ &omap443x_gpio1_hwmod,
+ &omap446x_gpio1_hwmod,
&omap44xx_gpio2_hwmod,
&omap44xx_gpio3_hwmod,
&omap44xx_gpio4_hwmod,
@@ -5110,6 +5470,9 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
/* hsi class */
/* &omap44xx_hsi_hwmod, */
+ /* gpu class */
+ &omap44xx_gpu_hwmod,
+
/* i2c class */
&omap44xx_i2c1_hwmod,
&omap44xx_i2c2_hwmod,
@@ -5122,13 +5485,19 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&omap44xx_ipu_c1_hwmod,
/* iss class */
-/* &omap44xx_iss_hwmod, */
+ &omap44xx_iss_hwmod,
+
+ /* fdif class */
+ &omap44xx_fdif_hwmod,
/* iva class */
&omap44xx_iva_hwmod,
&omap44xx_iva_seq0_hwmod,
&omap44xx_iva_seq1_hwmod,
+ /* sl2if class */
+ &omap44xx_sl2if_hwmod,
+
/* kbd class */
&omap44xx_kbd_hwmod,
@@ -5142,7 +5511,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&omap44xx_mcbsp4_hwmod,
/* mcpdm class */
-/* &omap44xx_mcpdm_hwmod, */
+ &omap44xx_mcpdm_hwmod,
/* mcspi class */
&omap44xx_mcspi1_hwmod,
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
index c784c12..903310f 100644
--- a/arch/arm/mach-omap2/omap_opp_data.h
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -49,6 +49,8 @@
*/
struct omap_opp_def {
char *hwmod_name;
+ char *voltdm_name;
+ char *clk_name;
unsigned long freq;
unsigned long u_volt;
@@ -59,9 +61,11 @@ struct omap_opp_def {
/*
* Initialization wrapper used to define an OPP for OMAP variants.
*/
-#define OPP_INITIALIZER(_hwmod_name, _enabled, _freq, _uv) \
+#define OPP_INITIALIZER(_hwmod_name, _clk_name, _voltdm_name, _enabled, _freq, _uv) \
{ \
.hwmod_name = _hwmod_name, \
+ .clk_name = _clk_name, \
+ .voltdm_name = _voltdm_name, \
.default_available = _enabled, \
.freq = _freq, \
.u_volt = _uv, \
@@ -86,11 +90,21 @@ extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
extern struct omap_volt_data omap34xx_vddmpu_volt_data[];
extern struct omap_volt_data omap34xx_vddcore_volt_data[];
+extern struct omap_vdd_dep_info omap34xx_vddmpu_dep_info[];
extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
extern struct omap_volt_data omap36xx_vddcore_volt_data[];
+extern struct omap_vdd_dep_info omap36xx_vddmpu_dep_info[];
-extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap443x_vdd_core_volt_data[];
+extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap446x_vdd_core_volt_data[];
+
+extern struct omap_vdd_dep_info omap443x_vddmpu_dep_info[];
+extern struct omap_vdd_dep_info omap443x_vddiva_dep_info[];
+extern struct omap_vdd_dep_info omap446x_vddmpu_dep_info[];
+extern struct omap_vdd_dep_info omap446x_vddiva_dep_info[];
#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/omap_pmic.c b/arch/arm/mach-omap2/omap_pmic.c
new file mode 100644
index 0000000..ddf1b9d
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_pmic.c
@@ -0,0 +1,75 @@
+/*
+ * Registration hooks for PMICs used with OMAP
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * 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/kernel.h>
+
+#include "voltage.h"
+
+#include "pm.h"
+
+/**
+ * omap_pmic_data_init() - trigger point for all PMIC initializers
+ */
+void __init omap_pmic_data_init(void)
+{
+ omap_twl_init();
+ omap_tps6236x_init();
+}
+
+/**
+ * omap_pmic_register_data() - Register the PMIC information to OMAP mapping
+ * @omap_pmic_maps: array ending with a empty element representing the maps
+ */
+int __init omap_pmic_register_data(struct omap_pmic_map *omap_pmic_maps)
+{
+ struct voltagedomain *voltdm;
+ struct omap_pmic_map *map;
+ int r;
+
+ if (!omap_pmic_maps)
+ return 0;
+
+ map = omap_pmic_maps;
+
+ while (map->name) {
+ if (!omap_chip_is(map->omap_chip))
+ goto next;
+
+ voltdm = voltdm_lookup(map->name);
+ if (IS_ERR_OR_NULL(voltdm)) {
+ pr_err("%s: unable to find map %s\n", __func__,
+ map->name);
+ goto next;
+ }
+ if (IS_ERR_OR_NULL(map->pmic_data)) {
+ pr_warning("%s: domain[%s] has no pmic data\n",
+ __func__, map->name);
+ goto next;
+ }
+
+ r = omap_voltage_register_pmic(voltdm, map->pmic_data);
+ if (r) {
+ pr_warning("%s: domain[%s] register returned %d\n",
+ __func__, map->name, r);
+ goto next;
+ }
+ if (map->special_action) {
+ r = map->special_action(voltdm);
+ WARN(r, "%s: domain[%s] action returned %d\n", __func__,
+ map->name, r);
+ }
+next:
+ map++;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/omap_tps6236x.c b/arch/arm/mach-omap2/omap_tps6236x.c
new file mode 100644
index 0000000..808d05c
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_tps6236x.c
@@ -0,0 +1,340 @@
+/*
+ * OMAP and TPS6236x specific initialization
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Vishwanath BS
+ * Nishanth Menon
+ *
+ * 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/kernel.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+
+#include "pm.h"
+#include "vc.h"
+#include "mux.h"
+
+/* Voltage limits supported */
+#define MIN_VOLTAGE_TPS62360_62_UV 770000
+#define MAX_VOLTAGE_TPS62360_62_UV 1400000
+
+#define MIN_VOLTAGE_TPS62361_UV 500000
+#define MAX_VOLTAGE_TPS62361_UV 1770000
+
+#define MAX_VOLTAGE_RAMP_TPS6236X_UV 32000
+
+/*
+ * This is the voltage delta between 2 values in voltage register.
+ * when switching voltage V1 to V2, TPS62361 can ramp up or down
+ * initially with step sizes of 20mV with a last step of 10mV.
+ * In the case of TPS6236[0|2], it is a constant 10mV steps
+ * we choose the 10mV step for linearity when SR is configured.
+ */
+#define STEP_SIZE_TPS6236X 10000
+
+/* I2C access parameters */
+#define I2C_TPS6236X_SLAVE_ADDR 0x60
+
+#define DEF_SET_REG(VSEL0, VSEL1) (((VSEL1) << 1| (VSEL0) << 0) & 0x3)
+#define REG_TPS6236X_SET_0 0x00
+#define REG_TPS6236X_SET_1 0x01
+#define REG_TPS6236X_SET_2 0x02
+#define REG_TPS6236X_SET_3 0x03
+#define REG_TPS6236X_CTRL 0x04
+#define REG_TPS6236X_TEMP 0x05
+#define REG_TPS6236X_RAMP_CTRL 0x06
+#define REG_TPS6236X_CHIP_ID0 0x08
+#define REG_TPS6236X_CHIP_ID1 0x09
+
+#define MODE_TPS6236X_AUTO_PFM_PWM 0x00
+#define MODE_TPS6236X_FORCE_PWM BIT(7)
+
+/* We use Auto PFM/PWM mode currently seems to have the best trade off */
+#define VOLTAGE_PFM_MODE_VAL MODE_TPS6236X_AUTO_PFM_PWM
+
+#define REG_TPS6236X_RAMP_CTRL_RMP_MASK (0x7 << 5)
+#define REG_TPS6236X_RAMP_CTRL_EN_DISC BIT(2)
+#define REG_TPS6236X_RAMP_CTRL_RAMP_PFM BIT(1)
+
+#define REG_TPS6236X_CTRL_PD_EN BIT(7)
+#define REG_TPS6236X_CTRL_PD_VSEL0 BIT(6)
+#define REG_TPS6236X_CTRL_PD_VSEL1 BIT(5)
+
+/* TWL usage */
+#define TWL6030_REG_SYSEN_CFG_GRP 0xB3
+#define TWL6030_BIT_APE_GRP BIT(0)
+
+/* Voltage params of the attached device (all in uV) */
+static unsigned long voltage_min;
+static unsigned long voltage_max;
+
+/* Which register do we use by default? */
+static int __initdata default_reg = -1;;
+
+/* Do we need to setup internal pullups? */
+static int __initdata pd_vsel0 = -1;
+static int __initdata pd_vsel1 = -1;
+
+static int __init _bd_setup(char *name,int gpio_vsel, int *pull, int *pd_vsel)
+{
+ int pull_dir;
+ int r;
+
+ if (gpio_vsel == -1) {
+ if (*pull != -1) {
+ *pd_vsel = (*pull == OMAP_PIN_OFF_OUTPUT_HIGH);
+ *pull = *pd_vsel;
+ } else {
+ *pull = 0;
+ }
+ return 0;
+ }
+
+ /* if we have a pull gpio, with bad dir, pull low */
+ if (*pull == -1 || (*pull != OMAP_PIN_OFF_OUTPUT_HIGH &&
+ *pull != OMAP_PIN_OFF_OUTPUT_LOW))
+ *pull = OMAP_PIN_OFF_OUTPUT_LOW;
+
+ r = omap_mux_init_gpio(gpio_vsel, *pull);
+ if (r) {
+ pr_err("%s: unable to mux gpio%d=%d\n", __func__,
+ gpio_vsel, r);
+ goto out;
+ }
+
+ pull_dir = (*pull == OMAP_PIN_OFF_OUTPUT_HIGH);
+ *pull = pull_dir;
+
+ r = gpio_request(gpio_vsel, name);
+ if (r) {
+ pr_err("%s: unable to req gpio%d=%d\n", __func__,
+ gpio_vsel, r);
+ goto out;
+ }
+ r = gpio_direction_output(gpio_vsel, pull_dir);
+ if (r) {
+ pr_err("%s: unable to pull[%d] gpio%d=%d\n", __func__,
+ gpio_vsel, pull_dir, r);
+ gpio_free(gpio_vsel);
+ goto out;
+ }
+out:
+ return r;
+}
+
+/* Convert the ramp voltage to ramp value. */
+static u8 __init tps6236x_ramp_value(unsigned long uv)
+{
+ if (!uv)
+ return 0;
+
+ if (uv > MAX_VOLTAGE_RAMP_TPS6236X_UV) {
+ pr_err("%s: uv%ld greater than max %d\n", __func__,
+ uv, MAX_VOLTAGE_RAMP_TPS6236X_UV);
+ uv = MAX_VOLTAGE_RAMP_TPS6236X_UV;
+ }
+ return fls(MAX_VOLTAGE_RAMP_TPS6236X_UV / uv) - 1;
+}
+
+static unsigned long tps6236x_vsel_to_uv(const u8 vsel)
+{
+ return (voltage_min +
+ (STEP_SIZE_TPS6236X * (vsel & ~VOLTAGE_PFM_MODE_VAL)));
+}
+
+static u8 tps6236x_uv_to_vsel(unsigned long uv)
+{
+ if (!uv)
+ return 0;
+
+ /* Round off requests to limits */
+ if (uv > voltage_max) {
+ pr_err("%s:Request for overvoltage[%ld] than supported[%ld]\n",
+ __func__, uv, voltage_max);
+ uv = voltage_max;
+ }
+ if (uv < voltage_min) {
+ pr_err("%s:Request for undervoltage[%ld] than supported[%ld]\n",
+ __func__, uv, voltage_min);
+ uv = voltage_min;
+ }
+ return DIV_ROUND_UP(uv - voltage_min, STEP_SIZE_TPS6236X) |
+ VOLTAGE_PFM_MODE_VAL;
+}
+
+static struct omap_voltdm_pmic omap4_mpu_pmic = {
+ .slew_rate = 8000,
+ .step_size = STEP_SIZE_TPS6236X,
+ .on_volt = 1375000,
+ .onlp_volt = 1375000,
+ .ret_volt = 830000,
+ .off_volt = 0,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = I2C_TPS6236X_SLAVE_ADDR,
+ .volt_reg_addr = REG_TPS6236X_SET_0,
+ .cmd_reg_addr = REG_TPS6236X_SET_0,
+ .i2c_high_speed = true,
+ .i2c_scll_low = 0x28,
+ .i2c_scll_high = 0x2C,
+ .i2c_hscll_low = 0x0B,
+ .i2c_hscll_high = 0x00,
+ .vsel_to_uv = tps6236x_vsel_to_uv,
+ .uv_to_vsel = tps6236x_uv_to_vsel,
+};
+
+/**
+ * omap4_twl_tps62361_enable() - Enable tps chip
+ *
+ * This function enables TPS chip by associating SYSEN signal
+ * to APE resource group of TWL6030.
+ *
+ * Returns 0 on sucess, error is returned if I2C read/write fails.
+ */
+static int __init omap4_twl_tps62361_enable(struct voltagedomain *voltdm)
+{
+ int ret = 0;
+ u8 val;
+
+ /* Dont trust the bootloader. start with max, pm will set to proper */
+ val = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
+ ret = omap_vc_bypass_send_i2c_msg(voltdm, voltdm->pmic->i2c_slave_addr,
+ default_reg, val);
+
+ /* Setup Ramp */
+ val = tps6236x_ramp_value(voltdm->pmic->slew_rate) <<
+ __ffs(REG_TPS6236X_RAMP_CTRL_RMP_MASK);
+ val &= REG_TPS6236X_RAMP_CTRL_RMP_MASK;
+
+ /* We would like to ramp the voltage asap */
+ val |= REG_TPS6236X_RAMP_CTRL_RAMP_PFM;
+
+ ret = omap_vc_bypass_send_i2c_msg(voltdm, voltdm->pmic->i2c_slave_addr,
+ REG_TPS6236X_RAMP_CTRL, val);
+ if (ret)
+ goto out;
+
+ /* Setup the internal pulls to select if needed */
+ if (pd_vsel0 != -1 || pd_vsel1 != -1) {
+ val = REG_TPS6236X_CTRL_PD_EN;
+ val |= (pd_vsel0) ? 0 : REG_TPS6236X_CTRL_PD_VSEL0;
+ val |= (pd_vsel1) ? 0 : REG_TPS6236X_CTRL_PD_VSEL1;
+ ret = omap_vc_bypass_send_i2c_msg(voltdm,
+ voltdm->pmic->i2c_slave_addr,
+ REG_TPS6236X_CTRL, val);
+ if (ret)
+ goto out;
+ }
+
+ /* Enable thermal shutdown - 0 is enable :) */
+ ret = omap_vc_bypass_send_i2c_msg(voltdm,
+ voltdm->pmic->i2c_slave_addr,
+ REG_TPS6236X_TEMP, 0x0);
+ if (ret)
+ goto out;
+
+ /* if we have to work with TWL */
+#ifdef CONFIG_TWL4030_CORE
+ ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, &val,
+ TWL6030_REG_SYSEN_CFG_GRP);
+ if (ret)
+ goto out;
+
+ val |= TWL6030_BIT_APE_GRP;
+ ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, val,
+ TWL6030_REG_SYSEN_CFG_GRP);
+#endif
+
+out:
+ if (ret)
+ pr_err("%s: Error enabling TPS(%d)\n", __func__, ret);
+
+ return ret;
+}
+
+static __initdata struct omap_pmic_map omap_tps_map[] = {
+ {
+ .name = "mpu",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
+ .pmic_data = &omap4_mpu_pmic,
+ .special_action = omap4_twl_tps62361_enable,
+ },
+ /* Terminator */
+ { .name = NULL,.pmic_data = NULL},
+};
+
+int __init omap_tps6236x_init(void)
+{
+ struct omap_pmic_map *map;
+
+ /* Without registers, I wont proceed */
+ if (default_reg == -1)
+ return -EINVAL;
+
+ map = omap_tps_map;
+
+ /* setup all the pmic's voltage addresses to the default one */
+ while (map->name) {
+ map->pmic_data->volt_reg_addr = default_reg;
+ map->pmic_data->cmd_reg_addr = default_reg;
+ map++;
+ }
+
+ return omap_pmic_register_data(omap_tps_map);
+}
+
+/**
+ * omap_tps6236x_board_setup() - provide the board config for TPS connect
+ * @use_62361: Do we use TPS62361 variant?
+ * @gpio_vsel0: If using GPIO to control VSEL0, provide gpio number, else -1
+ * @gpio_vsel1: If using GPIO to control VSEL1, provide gpio number, else -1
+ * @pull0: If using GPIO, provide mux mode OMAP_PIN_OFF_OUTPUT_[HIGH|LOW]
+ * else provide any internal pull required, -1 if unused.
+ * @pull1: If using GPIO, provide mux mode OMAP_PIN_OFF_OUTPUT_[HIGH|LOW]
+ * else provide any internal pull required, -1 if unused.
+ *
+ * TPS6236x variants of PMIC can be hooked in numerous combinations on to the
+ * board. Some platforms can choose to hardwire and save on a GPIO for other
+ * uses, while others may hook a single line for GPIO control and may ground
+ * the other line. support these configurations.
+ *
+ * WARNING: for platforms using GPIO, be careful to provide MUX setting
+ * considering OFF mode configuration as well.
+ */
+int __init omap_tps6236x_board_setup(bool use_62361, int gpio_vsel0,
+ int gpio_vsel1, int pull0, int pull1)
+{
+ int r;
+
+ r = _bd_setup("tps6236x_vsel0", gpio_vsel0, &pull0, &pd_vsel0);
+ if (r)
+ goto out;
+ r = _bd_setup("tps6236x_vsel1", gpio_vsel1, &pull1, &pd_vsel1);
+ if (r) {
+ if (gpio_vsel0 != -1)
+ gpio_free(gpio_vsel0);
+ goto out;
+ }
+
+ default_reg = ((pull1 & 0x1) << 1) | (pull0 & 0x1);
+
+ if (use_62361) {
+ voltage_min = MIN_VOLTAGE_TPS62361_UV;
+ voltage_max = MAX_VOLTAGE_TPS62361_UV;
+ } else {
+ voltage_min = MIN_VOLTAGE_TPS62360_62_UV;
+ voltage_max = MAX_VOLTAGE_TPS62360_62_UV;
+ }
+out:
+ return r;
+}
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 07d6140..0e30412 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -30,32 +30,13 @@
#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04
#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200
-#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14
-#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42
-#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18
-#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c
-
-#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18
-#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c
-#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
-#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
-
#define OMAP4_SRI2C_SLAVE_ADDR 0x12
#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
+#define OMAP4_VDD_MPU_SR_CMD_REG 0x56
#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
+#define OMAP4_VDD_IVA_SR_CMD_REG 0x5C
#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
-
-#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
-#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
-#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
-#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
-
-#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
-#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
-#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
-#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
-#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
-#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
+#define OMAP4_VDD_CORE_SR_CMD_REG 0x62
static bool is_offset_valid;
static u8 smps_offset;
@@ -95,6 +76,8 @@ static unsigned long twl6030_vsel_to_uv(const u8 vsel)
is_offset_valid = true;
}
+ if (!vsel)
+ return 0;
/*
* There is no specific formula for voltage to vsel
* conversion above 1.3V. There are special hardcoded
@@ -106,9 +89,9 @@ static unsigned long twl6030_vsel_to_uv(const u8 vsel)
return 1350000;
if (smps_offset & 0x8)
- return ((((vsel - 1) * 125) + 7000)) * 100;
+ return ((((vsel - 1) * 1266) + 70900)) * 10;
else
- return ((((vsel - 1) * 125) + 6000)) * 100;
+ return ((((vsel - 1) * 1266) + 60770)) * 10;
}
static u8 twl6030_uv_to_vsel(unsigned long uv)
@@ -127,6 +110,8 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
is_offset_valid = true;
}
+ if (!uv)
+ return 0x00;
/*
* There is no specific formula for voltage to vsel
* conversion above 1.3V. There are special hardcoded
@@ -134,16 +119,21 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
* hardcoding only for 1.35 V which is used for 1GH OPP for
* OMAP4430.
*/
- if (uv == 1350000)
+ if (uv > twl6030_vsel_to_uv(0x39)) {
+ if (uv == 1350000)
+ return 0x3A;
+ pr_err("%s:OUT OF RANGE! non mapped vsel for %ld Vs max %ld\n",
+ __func__, uv, twl6030_vsel_to_uv(0x39));
return 0x3A;
+ }
if (smps_offset & 0x8)
- return DIV_ROUND_UP(uv - 700000, 12500) + 1;
+ return DIV_ROUND_UP(uv - 709000, 12660) + 1;
else
- return DIV_ROUND_UP(uv - 600000, 12500) + 1;
+ return DIV_ROUND_UP(uv - 607700, 12660) + 1;
}
-static struct omap_volt_pmic_info omap3_mpu_volt_info = {
+static struct omap_voltdm_pmic omap3_mpu_pmic = {
.slew_rate = 4000,
.step_size = 12500,
.on_volt = 1200000,
@@ -158,12 +148,13 @@ static struct omap_volt_pmic_info omap3_mpu_volt_info = {
.vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .i2c_high_speed = true,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap3_core_volt_info = {
+static struct omap_voltdm_pmic omap3_core_pmic = {
.slew_rate = 4000,
.step_size = 12500,
.on_volt = 1200000,
@@ -178,18 +169,19 @@ static struct omap_volt_pmic_info omap3_core_volt_info = {
.vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .i2c_high_speed = true,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap4_mpu_volt_info = {
+static struct omap_voltdm_pmic omap443x_mpu_pmic = {
.slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1350000,
- .onlp_volt = 1350000,
- .ret_volt = 837500,
- .off_volt = 600000,
+ .step_size = 12660,
+ .on_volt = 1375000,
+ .onlp_volt = 1375000,
+ .ret_volt = 830000,
+ .off_volt = 0,
.volt_setup_time = 0,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
@@ -198,18 +190,24 @@ static struct omap_volt_pmic_info omap4_mpu_volt_info = {
.vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG,
+ .i2c_high_speed = true,
+ .i2c_scll_low = 0x28,
+ .i2c_scll_high = 0x2C,
+ .i2c_hscll_low = 0x0B,
+ .i2c_hscll_high = 0x00,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap4_iva_volt_info = {
+static struct omap_voltdm_pmic omap4_iva_pmic = {
.slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1100000,
- .onlp_volt = 1100000,
- .ret_volt = 837500,
- .off_volt = 600000,
+ .step_size = 12660,
+ .on_volt = 1188000,
+ .onlp_volt = 1188000,
+ .ret_volt = 830000,
+ .off_volt = 0,
.volt_setup_time = 0,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
@@ -218,18 +216,24 @@ static struct omap_volt_pmic_info omap4_iva_volt_info = {
.vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG,
+ .i2c_high_speed = true,
+ .i2c_scll_low = 0x28,
+ .i2c_scll_high = 0x2C,
+ .i2c_hscll_low = 0x0B,
+ .i2c_hscll_high = 0x00,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap4_core_volt_info = {
+static struct omap_voltdm_pmic omap443x_core_pmic = {
.slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1100000,
- .onlp_volt = 1100000,
- .ret_volt = 837500,
- .off_volt = 600000,
+ .step_size = 12660,
+ .on_volt = 1200000,
+ .onlp_volt = 1200000,
+ .ret_volt = 830000,
+ .off_volt = 0,
.volt_setup_time = 0,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
@@ -238,43 +242,47 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
.vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .i2c_high_speed = true,
+ .i2c_scll_low = 0x28,
+ .i2c_scll_high = 0x2C,
+ .i2c_hscll_low = 0x0B,
+ .i2c_hscll_high = 0x00,
+ .volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
-int __init omap4_twl_init(void)
-{
- struct voltagedomain *voltdm;
-
- if (!cpu_is_omap44xx())
- return -ENODEV;
-
- voltdm = omap_voltage_domain_lookup("mpu");
- omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
-
- voltdm = omap_voltage_domain_lookup("iva");
- omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
-
- voltdm = omap_voltage_domain_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
-
- return 0;
-}
+/* Core uses the MPU rail of 4430 */
+static struct omap_voltdm_pmic omap446x_core_pmic = {
+ .slew_rate = 4000,
+ .step_size = 12660,
+ .on_volt = 1200000,
+ .onlp_volt = 1200000,
+ .ret_volt = 830000,
+ .off_volt = 0,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .i2c_high_speed = true,
+ .i2c_scll_low = 0x28,
+ .i2c_scll_high = 0x2C,
+ .i2c_hscll_low = 0x0B,
+ .i2c_hscll_high = 0x00,
+ .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
-int __init omap3_twl_init(void)
+static int __init twl_set_sr(struct voltagedomain *voltdm)
{
- struct voltagedomain *voltdm;
-
- if (!cpu_is_omap34xx())
- return -ENODEV;
-
- if (cpu_is_omap3630()) {
- omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
- omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
- omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
- omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
- }
+ int r = 0;
/*
* The smartreflex bit on twl4030 specifies if the setting of voltage
@@ -286,15 +294,61 @@ int __init omap3_twl_init(void)
* voltage scaling will not function on TWL over I2C_SR.
*/
if (!twl_sr_enable_autoinit)
- omap3_twl_set_sr_bit(true);
+ r = omap3_twl_set_sr_bit(true);
+ return r;
+}
- voltdm = omap_voltage_domain_lookup("mpu");
- omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
+#define OMAP3_TWL4030_USED (CHIP_GE_OMAP3430ES2 | \
+ CHIP_GE_OMAP3630ES1_1 | \
+ CHIP_IS_OMAP3630ES1)
+
+static __initdata struct omap_pmic_map omap_twl_map[] = {
+ {
+ .name = "mpu_iva",
+ .omap_chip = OMAP_CHIP_INIT(OMAP3_TWL4030_USED),
+ .pmic_data = &omap3_mpu_pmic,
+ .special_action = twl_set_sr,
+ },
+ {
+ .name = "core",
+ .omap_chip = OMAP_CHIP_INIT(OMAP3_TWL4030_USED),
+ .pmic_data = &omap3_core_pmic,
+ },
+ {
+ .name = "mpu",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP443X),
+ .pmic_data = &omap443x_mpu_pmic,
+ },
+ {
+ .name = "core",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP443X),
+ .pmic_data = &omap443x_core_pmic,
+ },
+ {
+ .name = "core",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
+ .pmic_data = &omap446x_core_pmic,
+ },
+ {
+ .name = "iva",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pmic_data = &omap4_iva_pmic,
+ },
+ /* Terminator */
+ { .name = NULL, .pmic_data = NULL},
+};
- voltdm = omap_voltage_domain_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
+int __init omap_twl_init(void)
+{
+ /* Reuse OMAP3430 values */
+ if (cpu_is_omap3630()) {
+ omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
+ omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
+ omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
+ omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
+ }
- return 0;
+ return omap_pmic_register_data(omap_twl_map);
}
/**
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
index ab8b35b..1952854 100644
--- a/arch/arm/mach-omap2/opp.c
+++ b/arch/arm/mach-omap2/opp.c
@@ -22,6 +22,7 @@
#include <plat/omap_device.h>
#include "omap_opp_data.h"
+#include "dvfs.h"
/* Temp variable to allow multiple calls */
static u8 __initdata omap_table_init;
@@ -58,16 +59,16 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
struct device *dev;
if (!opp_def->hwmod_name) {
- pr_err("%s: NULL name of omap_hwmod, failing [%d].\n",
- __func__, i);
- return -EINVAL;
+ WARN(1, "%s: NULL name of omap_hwmod, failing"
+ " [%d].\n", __func__, i);
+ goto next;
}
oh = omap_hwmod_lookup(opp_def->hwmod_name);
if (!oh || !oh->od) {
- pr_warn("%s: no hwmod or odev for %s, [%d] "
+ WARN(1, "%s: no hwmod or odev for %s, [%d] "
"cannot add OPPs.\n", __func__,
opp_def->hwmod_name, i);
- return -EINVAL;
+ goto next;
}
dev = &oh->od->pdev.dev;
@@ -85,7 +86,14 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
"[%d] result=%d\n",
__func__, opp_def->freq,
opp_def->hwmod_name, i, r);
+
+ r = omap_dvfs_register_device(dev,
+ opp_def->voltdm_name, opp_def->clk_name);
+ if (r)
+ dev_err(dev, "%s:%s:err dvfs register %d %d\n",
+ __func__, opp_def->hwmod_name, r, i);
}
+next:
opp_def++;
}
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index d95f3f9..7662662 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -57,6 +57,24 @@ struct omap_volt_data omap34xx_vddcore_volt_data[] = {
VOLT_DATA_DEFINE(0, 0, 0, 0),
};
+/* OMAP 3430 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap34xx_vdd_mpu_core_dep_data[] = {
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP1_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP2_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP2_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP2_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP3_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP4_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP5_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV},
+};
+
+struct omap_vdd_dep_info omap34xx_vddmpu_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap34xx_vdd_mpu_core_dep_data,
+ .nr_dep_entries = ARRAY_SIZE(omap34xx_vdd_mpu_core_dep_data),
+ },
+ {.name = NULL, .dep_table = NULL, .nr_dep_entries = 0},
+};
+
/* 36xx */
/* VDD1 */
@@ -89,15 +107,15 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = {
static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
/* MPU OPP1 */
- OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV),
/* MPU OPP2 */
- OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV),
/* MPU OPP3 */
- OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV),
/* MPU OPP4 */
- OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
/* MPU OPP5 */
- OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
/*
* L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
@@ -107,47 +125,64 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
* impact that frequency will do to the MPU and the whole system in
* general.
*/
- OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV),
+ OPP_INITIALIZER("l3_main", "dpll3_ck", "core", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV),
/* L3 OPP2 */
- OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV),
+ OPP_INITIALIZER("l3_main", "dpll3_ck", "core", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV),
/* L3 OPP3 */
- OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV),
+ OPP_INITIALIZER("l3_main", "dpll3_ck", "core", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV),
/* DSP OPP1 */
- OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV),
/* DSP OPP2 */
- OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV),
/* DSP OPP3 */
- OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV),
/* DSP OPP4 */
- OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
/* DSP OPP5 */
- OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
};
static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
- OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
- OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
- OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV),
/* MPU OPP4 - OPP-SB */
- OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV),
+ OPP_INITIALIZER("mpu", "dpll1_ck", "mpu_iva", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV),
/* L3 OPP1 - OPP50 */
- OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV),
+ OPP_INITIALIZER("l3_main", "dpll3_ck", "core", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
- OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV),
+ OPP_INITIALIZER("l3_main", "dpll3_ck", "core", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV),
/* DSP OPP1 - OPP50 */
- OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV),
/* DSP OPP2 - OPP100 */
- OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV),
/* DSP OPP3 - OPP-Turbo */
- OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV),
/* DSP OPP4 - OPP-SB */
- OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV),
+ OPP_INITIALIZER("iva", "dpll2_ck", "mpu_iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV),
+};
+
+/* OMAP 3630 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap36xx_vdd_mpu_core_dep_data[] = {
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP50_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP50_UV},
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP100_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP120_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP1G_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV},
+};
+
+struct omap_vdd_dep_info omap36xx_vddmpu_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap36xx_vdd_mpu_core_dep_data,
+ .nr_dep_entries = ARRAY_SIZE(omap36xx_vdd_mpu_core_dep_data),
+ },
+ {.name = NULL, .dep_table = NULL, .nr_dep_entries = 0},
};
/**
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index 2293ba2..8d14e2f 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -1,7 +1,7 @@
/*
* OMAP4 OPP table definitions.
*
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
* Nishanth Menon
* Kevin Hilman
* Thara Gopinath
@@ -36,7 +36,7 @@
#define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000
#define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000
-struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
@@ -48,7 +48,7 @@ struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
#define OMAP4430_VDD_IVA_OPP100_UV 1188000
#define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000
-struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
@@ -58,33 +58,194 @@ struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
#define OMAP4430_VDD_CORE_OPP50_UV 1025000
#define OMAP4430_VDD_CORE_OPP100_UV 1200000
-struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+struct omap_volt_data omap443x_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
VOLT_DATA_DEFINE(0, 0, 0, 0),
};
+/* Dependency of domains are as follows for OMAP4430 (OPP based):
+ *
+ * MPU IVA CORE
+ * 50 50 50+
+ * 50 100+ 100
+ * 100+ 50 100
+ * 100+ 100+ 100
+ */
+
+/* OMAP 4430 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap443x_vdd_mpu_core_dep_data[] = {
+ {.main_vdd_volt = OMAP4430_VDD_MPU_OPP50_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP50_UV},
+ {.main_vdd_volt = OMAP4430_VDD_MPU_OPP100_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP4430_VDD_MPU_OPPTURBO_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP4430_VDD_MPU_OPPNITRO_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP100_UV},
+};
+
+struct omap_vdd_dep_info omap443x_vddmpu_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap443x_vdd_mpu_core_dep_data,
+ .nr_dep_entries = ARRAY_SIZE(omap443x_vdd_mpu_core_dep_data),
+ },
+ {.name = NULL, .dep_table = NULL, .nr_dep_entries = 0},
+};
-static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
+/* OMAP 4430 MPU IVA VDD dependency table */
+static struct omap_vdd_dep_volt omap443x_vdd_iva_core_dep_data[] = {
+ {.main_vdd_volt = OMAP4430_VDD_IVA_OPP50_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP50_UV},
+ {.main_vdd_volt = OMAP4430_VDD_IVA_OPP100_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP4430_VDD_IVA_OPPTURBO_UV, .dep_vdd_volt = OMAP4430_VDD_CORE_OPP100_UV},
+};
+
+struct omap_vdd_dep_info omap443x_vddiva_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap443x_vdd_iva_core_dep_data,
+ .nr_dep_entries = ARRAY_SIZE(omap443x_vdd_iva_core_dep_data),
+ },
+ {.name = NULL, .dep_table = NULL, .nr_dep_entries = 0},
+};
+
+static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
- OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
+ OPP_INITIALIZER("mpu", "dpll_mpu_ck", "mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
- OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV),
+ OPP_INITIALIZER("mpu", "dpll_mpu_ck", "mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
- OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV),
+ OPP_INITIALIZER("mpu", "dpll_mpu_ck", "mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV),
/* MPU OPP4 - OPP-SB */
- OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV),
+ OPP_INITIALIZER("mpu", "dpll_mpu_ck", "mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV),
/* L3 OPP1 - OPP50 */
- OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV),
+ OPP_INITIALIZER("l3_main_1", "virt_l3_ck", "core", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
- OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV),
+ OPP_INITIALIZER("l3_main_1", "virt_l3_ck", "core", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV),
/* IVA OPP1 - OPP50 */
- OPP_INITIALIZER("iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV),
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV),
/* IVA OPP2 - OPP100 */
- OPP_INITIALIZER("iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV),
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV),
/* IVA OPP3 - OPP-Turbo */
- OPP_INITIALIZER("iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV),
- /* TODO: add DSP, aess, fdif, gpu */
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV),
+ /* SGX OPP1 - OPP50 */
+ OPP_INITIALIZER("gpu", "dpll_per_m7x2_ck", "core", true, 153600000, OMAP4430_VDD_CORE_OPP50_UV),
+ /* SGX OPP2 - OPP100 */
+ OPP_INITIALIZER("gpu", "dpll_per_m7x2_ck", "core", true, 307200000, OMAP4430_VDD_CORE_OPP50_UV),
+ /* TODO: add DSP, aess, fdif */
+};
+
+#define OMAP4460_VDD_MPU_OPP50_UV 1025000
+#define OMAP4460_VDD_MPU_OPP100_UV 1200000
+#define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000
+#define OMAP4460_VDD_MPU_OPPNITRO_UV 1375000
+
+struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_IVA_OPP50_UV 1025000
+#define OMAP4460_VDD_IVA_OPP100_UV 1200000
+#define OMAP4460_VDD_IVA_OPPTURBO_UV 1313000
+#define OMAP4460_VDD_IVA_OPPNITRO_UV 1375000
+
+struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_CORE_OPP50_UV 1025000
+#define OMAP4460_VDD_CORE_OPP100_UV 1200000
+#define OMAP4460_VDD_CORE_OPP100_OV_UV 1250000
+
+struct omap_volt_data omap446x_vdd_core_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* OMAP 4460 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap446x_vdd_mpu_core_dep_data[] = {
+ {.main_vdd_volt = OMAP4460_VDD_MPU_OPP50_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP50_UV},
+ {.main_vdd_volt = OMAP4460_VDD_MPU_OPP100_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP4460_VDD_MPU_OPPTURBO_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP4460_VDD_MPU_OPPNITRO_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP100_UV},
+};
+
+struct omap_vdd_dep_info omap446x_vddmpu_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap446x_vdd_mpu_core_dep_data,
+ .nr_dep_entries = ARRAY_SIZE(omap446x_vdd_mpu_core_dep_data),
+ },
+ {.name = NULL, .dep_table = NULL, .nr_dep_entries = 0},
+};
+
+/* OMAP 4460 MPU IVA VDD dependency table */
+static struct omap_vdd_dep_volt omap446x_vdd_iva_core_dep_data[] = {
+ {.main_vdd_volt = OMAP4460_VDD_IVA_OPP50_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP50_UV},
+ {.main_vdd_volt = OMAP4460_VDD_IVA_OPP100_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP4460_VDD_IVA_OPPTURBO_UV, .dep_vdd_volt = OMAP4460_VDD_CORE_OPP100_UV},
+};
+
+struct omap_vdd_dep_info omap446x_vddiva_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap446x_vdd_iva_core_dep_data,
+ .nr_dep_entries = ARRAY_SIZE(omap446x_vdd_iva_core_dep_data),
+ },
+ {.name = NULL, .dep_table = NULL, .nr_dep_entries = 0},
+};
+
+static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
+ /* MPU OPP1 - OPP50 */
+ OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
+ /* MPU OPP2 - OPP100 */
+ OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
+ /* MPU OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
+ /*
+ * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
+ * recommends TPS623631 - confirm and enable the opp in board file
+ * XXX: May be we should enable these based on mpu capability and
+ * Exception board files disable it...
+ */
+ OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+ /* MPU OPP4 - OPP-Nitro SpeedBin */
+ OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+ /* L3 OPP1 - OPP50 */
+ OPP_INITIALIZER("l3_main_1", "virt_l3_ck", "core", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
+ /* L3 OPP2 - OPP100 */
+ OPP_INITIALIZER("l3_main_1", "virt_l3_ck", "core", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
+ /* IVA OPP1 - OPP50 */
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
+ /* IVA OPP2 - OPP100 */
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
+ /*
+ * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
+ * recommends Phoenix VCORE2 which can supply only 600mA - so the ones
+ * above this OPP frequency, even though OMAP is capable, should be
+ * enabled by board file which is sure of the chip power capability
+ */
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
+ /* IVA OPP4 - OPP-Nitro */
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+ /* IVA OPP5 - OPP-Nitro SpeedBin*/
+ OPP_INITIALIZER("iva", "dpll_iva_m5x2_ck", "iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+
+ /* SGX OPP1 - OPP50 */
+ OPP_INITIALIZER("gpu", "dpll_per_m7x2_ck", "core", true, 153600000, OMAP4460_VDD_CORE_OPP50_UV),
+ /* SGX OPP2 - OPP100 */
+ OPP_INITIALIZER("gpu", "dpll_per_m7x2_ck", "core", true, 307200000, OMAP4460_VDD_CORE_OPP100_UV),
+ /* SGX OPP3 - OPPOV */
+ OPP_INITIALIZER("gpu", "dpll_per_m7x2_ck", "core", true, 384000000, OMAP4460_VDD_CORE_OPP100_OV_UV),
+
+ /* TODO: add DSP, aess, fdif */
};
/**
@@ -96,10 +257,12 @@ int __init omap4_opp_init(void)
if (!cpu_is_omap44xx())
return r;
-
- r = omap_init_opp_table(omap44xx_opp_def_list,
- ARRAY_SIZE(omap44xx_opp_def_list));
-
+ if (cpu_is_omap443x())
+ r = omap_init_opp_table(omap443x_opp_def_list,
+ ARRAY_SIZE(omap443x_opp_def_list));
+ else if (cpu_is_omap446x())
+ r = omap_init_opp_table(omap446x_opp_def_list,
+ ARRAY_SIZE(omap446x_opp_def_list));
return r;
}
device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index a5a83b3..0ef8d69 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -189,7 +189,7 @@ static struct dentry *pm_dbg_dir;
static int pm_dbg_init_done;
-static int __init pm_dbg_init(void);
+static int pm_dbg_init(void);
enum {
DEBUG_FILE_COUNTERS = 0,
@@ -595,7 +595,7 @@ static int option_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
-static int __init pm_dbg_init(void)
+static int pm_dbg_init(void)
{
int i;
struct dentry *d;
@@ -604,9 +604,11 @@ static int __init pm_dbg_init(void)
if (pm_dbg_init_done)
return 0;
- if (cpu_is_omap34xx())
+ if (cpu_is_omap34xx()) {
pm_dbg_reg_modules = omap3_pm_reg_modules;
- else {
+ } else if (cpu_is_omap44xx()) {
+ /* Allow pm_dbg_init on OMAP4. */
+ } else {
printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
return -ENODEV;
}
@@ -622,6 +624,9 @@ static int __init pm_dbg_init(void)
pwrdm_for_each(pwrdms_setup, (void *)d);
+ if (cpu_is_omap44xx())
+ goto skip_reg_debufs;
+
pm_dbg_dir = debugfs_create_dir("registers", d);
if (IS_ERR(pm_dbg_dir))
return PTR_ERR(pm_dbg_dir);
@@ -641,6 +646,8 @@ static int __init pm_dbg_init(void)
&enable_off_mode, &pm_dbg_option_fops);
(void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUSR, d,
&sleep_while_idle, &pm_dbg_option_fops);
+
+skip_reg_debufs:
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUSR, d,
&wakeup_timer_seconds, &pm_dbg_option_fops);
(void) debugfs_create_file("wakeup_timer_milliseconds",
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 49486f5..744431c 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -36,18 +36,21 @@ struct device *omap2_get_mpuss_device(void)
WARN_ON_ONCE(!mpu_dev);
return mpu_dev;
}
+EXPORT_SYMBOL(omap2_get_mpuss_device);
struct device *omap2_get_iva_device(void)
{
WARN_ON_ONCE(!iva_dev);
return iva_dev;
}
+EXPORT_SYMBOL(omap2_get_iva_device);
struct device *omap2_get_l3_device(void)
{
WARN_ON_ONCE(!l3_dev);
return l3_dev;
}
+EXPORT_SYMBOL(omap2_get_l3_device);
struct device *omap4_get_dsp_device(void)
{
@@ -106,8 +109,9 @@ static void omap2_init_processor_devices(void)
int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
{
u32 cur_state;
- int sleep_switch = 0;
+ int sleep_switch = -1;
int ret = 0;
+ int hwsup = 0;
if (pwrdm == NULL || IS_ERR(pwrdm))
return -EINVAL;
@@ -127,6 +131,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
sleep_switch = LOWPOWERSTATE_SWITCH;
} else {
+ hwsup = clkdm_is_idle(pwrdm->pwrdm_clkdms[0]);
clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
pwrdm_wait_transition(pwrdm);
sleep_switch = FORCEWAKEUP_SWITCH;
@@ -142,7 +147,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
switch (sleep_switch) {
case FORCEWAKEUP_SWITCH:
- if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
+ if (hwsup)
clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
else
clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
@@ -174,14 +179,15 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
struct voltagedomain *voltdm;
struct clk *clk;
struct opp *opp;
- unsigned long freq, bootup_volt;
+ unsigned long freq_cur, freq_valid, bootup_volt;
+ int ret = -EINVAL;
if (!vdd_name || !clk_name || !dev) {
printk(KERN_ERR "%s: Invalid parameters!\n", __func__);
goto exit;
}
- voltdm = omap_voltage_domain_lookup(vdd_name);
+ voltdm = voltdm_lookup(vdd_name);
if (IS_ERR(voltdm)) {
printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n",
__func__, vdd_name);
@@ -195,25 +201,78 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
goto exit;
}
- freq = clk->rate;
- clk_put(clk);
+ freq_cur = clk->rate;
+ freq_valid = freq_cur;
- opp = opp_find_freq_ceil(dev, &freq);
+ rcu_read_lock();
+ opp = opp_find_freq_ceil(dev, &freq_valid);
if (IS_ERR(opp)) {
- printk(KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n",
- __func__, vdd_name);
- goto exit;
+ opp = opp_find_freq_floor(dev, &freq_valid);
+ if (IS_ERR(opp)) {
+ rcu_read_unlock();
+ pr_err("%s: no boot OPP match for %ld on vdd_%s\n",
+ __func__, freq_cur, vdd_name);
+ ret = -ENOENT;
+ goto exit_ck;
+ }
}
bootup_volt = opp_get_voltage(opp);
+ rcu_read_unlock();
if (!bootup_volt) {
printk(KERN_ERR "%s: unable to find voltage corresponding"
"to the bootup OPP for vdd_%s\n", __func__, vdd_name);
- goto exit;
+ ret = -ENOENT;
+ goto exit_ck;
}
- omap_voltage_scale_vdd(voltdm, bootup_volt);
- return 0;
+ /*
+ * Frequency and Voltage have to be sequenced: if we move from
+ * a lower frequency to higher frequency, raise voltage, followed by
+ * frequency, and vice versa. we assume that the voltage at boot
+ * is the required voltage for the frequency it was set for.
+ * NOTE:
+ * we can check the frequency, but there is numerous ways to set
+ * voltage. We play the safe path and just set the voltage.
+ */
+
+ if (freq_cur < freq_valid) {
+ ret = voltdm_scale(voltdm, bootup_volt);
+ if (ret) {
+ pr_err("%s: Fail set voltage-%s(f=%ld v=%ld)on vdd%s\n",
+ __func__, vdd_name, freq_valid,
+ bootup_volt, vdd_name);
+ goto exit_ck;
+ }
+ }
+
+ /* Set freq only if there is a difference in freq */
+ if (freq_valid != freq_cur) {
+ ret = clk_set_rate(clk, freq_valid);
+ if (ret) {
+ pr_err("%s: Fail set clk-%s(f=%ld v=%ld)on vdd%s\n",
+ __func__, clk_name, freq_valid,
+ bootup_volt, vdd_name);
+ goto exit_ck;
+ }
+ }
+
+ if (freq_cur >= freq_valid) {
+ ret = voltdm_scale(voltdm, bootup_volt);
+ if (ret) {
+ pr_err("%s: Fail set voltage-%s(f=%ld v=%ld)on vdd%s\n",
+ __func__, clk_name, freq_valid,
+ bootup_volt, vdd_name);
+ goto exit_ck;
+ }
+ }
+
+ ret = 0;
+exit_ck:
+ clk_put(clk);
+
+ if (!ret)
+ return 0;
exit:
printk(KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n",
@@ -226,7 +285,7 @@ static void __init omap3_init_voltages(void)
if (!cpu_is_omap34xx())
return;
- omap2_set_init_voltage("mpu", "dpll1_ck", mpu_dev);
+ omap2_set_init_voltage("mpu_iva", "dpll1_ck", mpu_dev);
omap2_set_init_voltage("core", "l3_ick", l3_dev);
}
@@ -235,8 +294,13 @@ static void __init omap4_init_voltages(void)
if (!cpu_is_omap44xx())
return;
- omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
- omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
+ if (cpu_is_omap446x()) {
+ omap2_set_init_voltage("mpu", "virt_dpll_mpu_ck", mpu_dev);
+ omap2_set_init_voltage("core", "virt_l3_ck", l3_dev);
+ } else {
+ omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
+ omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
+ }
omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev);
}
@@ -251,9 +315,8 @@ postcore_initcall(omap2_common_pm_init);
static int __init omap2_common_pm_late_init(void)
{
- /* Init the OMAP TWL parameters */
- omap3_twl_init();
- omap4_twl_init();
+ /* Init the OMAP PMIC parameters */
+ omap_pmic_data_init();
/* Init the voltage layer */
omap_voltage_late_init();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 45bcfce..451b1da 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -19,8 +19,12 @@ extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int);
extern void omap_sram_idle(void);
extern int omap3_can_sleep(void);
+extern int omap4_can_sleep(void);
extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
extern int omap3_idle_init(void);
+extern int omap4_idle_init(void);
+extern void omap4_enter_sleep(unsigned int cpu, unsigned int power_state);
+extern void omap4_trigger_ioctrl(void);
#if defined(CONFIG_PM_OPP)
extern int omap3_opp_init(void);
@@ -125,16 +129,56 @@ static inline int omap_devinit_smartreflex(void)
static inline void omap_enable_smartreflex_on_init(void) {}
#endif
+/**
+ * struct omap_pmic_map - Describe the OMAP PMIC data for OMAP
+ * @name: name of the voltage domain
+ * @pmic_data: pmic data associated with it
+ * @omap_chip: initialize with OMAP_CHIP_INIT the OMAP chips this data maps to
+ * @special_action: callback for any specific action to take for that map
+ *
+ * Since we support multiple PMICs each potentially functioning on multiple
+ * OMAP devices, we describe the parameters in a map allowing us to reuse the
+ * data as necessary.
+ */
+struct omap_pmic_map {
+ char *name;
+ struct omap_voltdm_pmic *pmic_data;
+ struct omap_chip_id omap_chip;
+ int (*special_action)(struct voltagedomain *);
+};
+
+#ifdef CONFIG_PM
+extern int omap_pmic_register_data(struct omap_pmic_map *map);
+#else
+static inline int omap_pmic_register_data(struct omap_pmic_map *map)
+{
+ return -EINVAL;
+}
+#endif
+extern void omap_pmic_data_init(void);
+
#ifdef CONFIG_TWL4030_CORE
-extern int omap3_twl_init(void);
-extern int omap4_twl_init(void);
+extern int omap_twl_init(void);
extern int omap3_twl_set_sr_bit(bool enable);
#else
-static inline int omap3_twl_init(void)
+static inline int omap_twl_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
+#ifdef CONFIG_OMAP_TPS6236X
+extern int omap_tps6236x_board_setup(bool use_62361, int gpio_vsel0,
+ int gpio_vsel1, int pull0, int pull1);
+extern int omap_tps6236x_init(void);
+
+#else
+static inline int omap_tps6236x_board_setup(bool use_62361, int gpio_vsel0,
+ int gpio_vsel1, int pull0, int pull1)
{
return -EINVAL;
}
-static inline int omap4_twl_init(void)
+static inline int omap_tps6236x_init(void)
{
return -EINVAL;
}
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 59a870b..40d8779 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -1,8 +1,9 @@
/*
* OMAP4 Power Management Routines
*
- * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010-2011 Texas Instruments, Inc.
* Rajendra Nayak <rnayak@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.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
@@ -12,12 +13,31 @@
#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/module.h>
+#include <linux/clk.h>
#include <linux/list.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
-#include "powerdomain.h"
#include <mach/omap4-common.h>
+#include <plat/common.h>
+
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "pm.h"
+#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prm44xx.h"
+#include "prminst44xx.h"
+
+#include "clock.h"
+#include "cm2_44xx.h"
+#include "cm1_44xx.h"
+#include "cm-regbits-44xx.h"
+#include "cminst44xx.h"
+
struct power_state {
struct powerdomain *pwrdm;
@@ -29,11 +49,129 @@ struct power_state {
};
static LIST_HEAD(pwrst_list);
+static struct powerdomain *mpu_pwrdm, *cpu0_pwrdm;
+static struct powerdomain *core_pwrdm, *per_pwrdm;
+
+#define MAX_IOPAD_LATCH_TIME 1000
+void omap4_trigger_ioctrl(void)
+{
+ int i = 0;
+
+ /* Trigger WUCLKIN enable */
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, OMAP4430_WUCLK_CTRL_MASK,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
+ omap_test_timeout(
+ ((omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET)
+ >> OMAP4430_WUCLK_STATUS_SHIFT) == 1),
+ MAX_IOPAD_LATCH_TIME, i);
+ /* Trigger WUCLKIN disable */
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
+ return;
+}
#ifdef CONFIG_SUSPEND
+/* This is a common low power function called from suspend and
+ * cpuidle
+ */
+void omap4_enter_sleep(unsigned int cpu, unsigned int power_state)
+{
+ int cpu0_next_state = PWRDM_POWER_ON;
+ int per_next_state = PWRDM_POWER_ON;
+ int core_next_state = PWRDM_POWER_ON;
+
+ pwrdm_clear_all_prev_pwrst(cpu0_pwrdm);
+ pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
+ pwrdm_clear_all_prev_pwrst(core_pwrdm);
+ pwrdm_clear_all_prev_pwrst(per_pwrdm);
+
+ cpu0_next_state = pwrdm_read_next_pwrst(cpu0_pwrdm);
+ per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
+ core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
+
+ if (core_next_state < PWRDM_POWER_ON) {
+ omap_uart_prepare_idle(0);
+ omap_uart_prepare_idle(1);
+ omap_uart_prepare_idle(2);
+ omap_uart_prepare_idle(3);
+ omap2_gpio_prepare_for_idle(0);
+ omap4_trigger_ioctrl();
+ }
+
+ omap4_enter_lowpower(cpu, power_state);
+
+ if (core_next_state < PWRDM_POWER_ON) {
+ omap2_gpio_resume_after_idle();
+ omap_uart_resume_idle(0);
+ omap_uart_resume_idle(1);
+ omap_uart_resume_idle(2);
+ omap_uart_resume_idle(3);
+ }
+
+ return;
+}
+
static int omap4_pm_suspend(void)
{
- do_wfi();
+ struct power_state *pwrst;
+ int state, ret = 0;
+
+ /* Wakeup timer from suspend */
+ if (wakeup_timer_seconds || wakeup_timer_milliseconds)
+ omap2_pm_wakeup_on_timer(wakeup_timer_seconds,
+ wakeup_timer_milliseconds);
+
+ /* Save current powerdomain state */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+ }
+
+ /* Set targeted power domain states by suspend */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+#ifdef CONFIG_OMAP_ALLOW_OSWR
+ if ((!strcmp(pwrst->pwrdm->name, "cpu0_pwrdm")) ||
+ (!strcmp(pwrst->pwrdm->name, "cpu1_pwrdm")))
+ continue;
+
+ /*OSWR is supported on silicon > ES2.0 */
+ if ((pwrst->pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET)
+ && (omap_rev() >= OMAP4430_REV_ES2_1))
+ pwrdm_set_logic_retst(pwrst->pwrdm,
+ PWRDM_POWER_OFF);
+#endif
+ pwrst->next_state = PWRDM_POWER_RET;
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+ }
+
+ /*
+ * For MPUSS to hit power domain retention(CSWR or OSWR),
+ * CPU0 and CPU1 power domain needs to be in OFF or DORMANT
+ * state. For MPUSS to reach off-mode. CPU0 and CPU1 power domain
+ * should be in off state.
+ * Only master CPU followes suspend path. All other CPUs follow
+ * cpu-hotplug path in system wide suspend. On OMAP4, CPU power
+ * domain CSWR is not supported by hardware.
+ * More details can be found in OMAP4430 TRM section 4.3.4.2.
+ */
+ omap_uart_prepare_suspend();
+ omap4_enter_sleep(0, PWRDM_POWER_OFF);
+
+ /* Restore next powerdomain state */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+ if (state > pwrst->next_state) {
+ pr_info("Powerdomain (%s) didn't enter "
+ "target state %d\n",
+ pwrst->pwrdm->name, pwrst->next_state);
+ ret = -1;
+ }
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+ }
+ if (ret)
+ pr_err("Could not enter target state in pm_suspend\n");
+ else
+ pr_err("Successfully put all powerdomains to target state\n");
+
return 0;
}
@@ -71,8 +209,26 @@ static const struct platform_suspend_ops omap_pm_ops = {
.enter = omap4_pm_enter,
.valid = suspend_valid_only_mem,
};
+#else
+void omap4_enter_sleep(unsigned int cpu, unsigned int power_state){ return; }
#endif /* CONFIG_SUSPEND */
+/*
+ * Enable hardware supervised mode for all clockdomains if it's
+ * supported. Initiate sleep transition for other clockdomains, if
+ * they are not used
+ */
+static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
+{
+ if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+ clkdm_allow_idle(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
+ atomic_read(&clkdm->usecount) == 0)
+ clkdm_sleep(clkdm);
+ return 0;
+}
+
+
static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
{
struct power_state *pwrst;
@@ -83,11 +239,87 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
if (!pwrst)
return -ENOMEM;
+
pwrst->pwrdm = pwrdm;
- pwrst->next_state = PWRDM_POWER_ON;
+ if ((!strcmp(pwrdm->name, "mpu_pwrdm")) ||
+ (!strcmp(pwrdm->name, "core_pwrdm")) ||
+ (!strcmp(pwrdm->name, "cpu0_pwrdm")) ||
+ (!strcmp(pwrdm->name, "cpu1_pwrdm")))
+ pwrst->next_state = PWRDM_POWER_ON;
+ else
+ pwrst->next_state = PWRDM_POWER_RET;
list_add(&pwrst->node, &pwrst_list);
- return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state);
+ return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+}
+
+static void __init prcm_setup_regs(void)
+{
+ /* Enable IO_ST interrupt */
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_IO_ST_MASK, OMAP4430_IO_ST_MASK,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET);
+
+ /* Enable GLOBAL_WUEN */
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_GLOBAL_WUEN_MASK,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
+ /*
+ * Errata ID: i608 Impacted OMAP4430 ES 1.0,2.0,2.1,2.2
+ * On OMAP4, Retention-Till-Access Memory feature is not working
+ * reliably and hardware recommondation is keep it disabled by
+ * default
+ */
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_DISABLE_RTA_EXPORT_MASK,
+ 0x1 << OMAP4430_DISABLE_RTA_EXPORT_SHIFT,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_SRAM_WKUP_SETUP_OFFSET);
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_DISABLE_RTA_EXPORT_MASK,
+ 0x1 << OMAP4430_DISABLE_RTA_EXPORT_SHIFT,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_LDO_SRAM_CORE_SETUP_OFFSET);
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_DISABLE_RTA_EXPORT_MASK,
+ 0x1 << OMAP4430_DISABLE_RTA_EXPORT_SHIFT,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_LDO_SRAM_MPU_SETUP_OFFSET);
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_DISABLE_RTA_EXPORT_MASK,
+ 0x1 << OMAP4430_DISABLE_RTA_EXPORT_SHIFT,
+ OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_LDO_SRAM_IVA_SETUP_OFFSET);
+ /* Toggle CLKREQ in RET and OFF states */
+ omap4_prminst_write_inst_reg(0x2, OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_CLKREQCTRL_OFFSET);
+ /*
+ * De-assert PWRREQ signal in Device OFF state
+ * 0x3: PWRREQ is de-asserted if all voltage domain are in
+ * OFF state. Conversely, PWRREQ is asserted upon any
+ * voltage domain entering or staying in ON or SLEEP or
+ * RET state.
+ */
+ omap4_prminst_write_inst_reg(0x3, OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_PWRREQCTRL_OFFSET);
+}
+static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+{
+ u32 irqenable_mpu, irqstatus_mpu;
+
+ irqenable_mpu = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_OFFSET);
+ irqstatus_mpu = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
+
+ /* Check if a IO_ST interrupt */
+ if (irqstatus_mpu & OMAP4430_IO_ST_MASK) {
+ omap4_trigger_ioctrl();
+ }
+
+ /* Clear the interrupt */
+ irqstatus_mpu &= irqenable_mpu;
+ omap4_prm_write_inst_reg(irqstatus_mpu, OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
+
+ return IRQ_HANDLED;
+}
+
+int omap4_can_sleep(void)
+{
+ if (!omap_uart_can_sleep())
+ return -1;
+ return 0;
}
/**
@@ -99,22 +331,83 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
static int __init omap4_pm_init(void)
{
int ret;
+ struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
+ struct clockdomain *ducati_clkdm, *l3_2_clkdm;
if (!cpu_is_omap44xx())
return -ENODEV;
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+ return -ENODEV;
+ }
+
pr_err("Power Management for TI OMAP4.\n");
+ prcm_setup_regs();
+
+ ret = request_irq(OMAP44XX_IRQ_PRCM,
+ (irq_handler_t)prcm_interrupt_handler,
+ IRQF_DISABLED, "prcm", NULL);
+ if (ret) {
+ printk(KERN_ERR "request_irq failed to register for 0x%x\n",
+ OMAP44XX_IRQ_PRCM);
+ goto err2;
+ }
ret = pwrdm_for_each(pwrdms_setup, NULL);
if (ret) {
pr_err("Failed to setup powerdomains\n");
goto err2;
}
+ /*
+ * The dynamic dependency between MPUSS -> MEMIF and
+ * MPUSS -> L3_* and DUCATI -> doesn't work as expected.
+ * The hardware recommendation is to keep above dependencies.
+ * Without this system locks up or randomly crashesh.
+ */
+ mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
+ emif_clkdm = clkdm_lookup("l3_emif_clkdm");
+ l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
+ l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
+ ducati_clkdm = clkdm_lookup("ducati_clkdm");
+ if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
+ (!l3_2_clkdm) || (!ducati_clkdm))
+ goto err2;
+
+ ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
+ ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
+ ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
+ ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
+ ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
+ if (ret) {
+ pr_err("Failed to add MPUSS -> L3/EMIF, DUCATI -> L3"
+ "wakeup dependency\n");
+ goto err2;
+ }
+
+ (void) clkdm_for_each(clkdms_setup, NULL);
+
+ pr_info("OMAP4 PM: Temporary static dependency added between"
+ "MPUSS <-> EMIF and MPUSS <-> L3_MAIN_1.\n");
+
+ ret = omap4_mpuss_init();
+ if (ret) {
+ pr_err("Failed to initialise OMAP4 MPUSS\n");
+ goto err2;
+ }
+
#ifdef CONFIG_SUSPEND
suspend_set_ops(&omap_pm_ops);
#endif /* CONFIG_SUSPEND */
+ mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
+ cpu0_pwrdm = pwrdm_lookup("cpu0_pwrdm");
+ core_pwrdm = pwrdm_lookup("core_pwrdm");
+ per_pwrdm = pwrdm_lookup("l4per_pwrdm");
+
+ omap4_idle_init();
+
err2:
return ret;
}
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 9af0847..71d9b75 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -19,6 +19,8 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/slab.h>
+
#include <trace/events/power.h>
#include "cm2xxx_3xxx.h"
@@ -77,6 +79,7 @@ static struct powerdomain *_pwrdm_lookup(const char *name)
static int _pwrdm_register(struct powerdomain *pwrdm)
{
int i;
+ struct voltagedomain *voltdm;
if (!pwrdm || !pwrdm->name)
return -EINVAL;
@@ -94,6 +97,16 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
if (_pwrdm_lookup(pwrdm->name))
return -EEXIST;
+ voltdm = voltdm_lookup(pwrdm->voltdm.name);
+ if (!voltdm) {
+ pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
+ pwrdm->name, pwrdm->voltdm.name);
+ return -EINVAL;
+ }
+ pwrdm->voltdm.ptr = voltdm;
+ INIT_LIST_HEAD(&pwrdm->voltdm_node);
+ voltdm_add_pwrdm(voltdm, pwrdm);
+
list_add(&pwrdm->node, &pwrdm_list);
/* Initialize the powerdomain's state counter */
@@ -108,6 +121,13 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
pwrdm->state = pwrdm_read_pwrst(pwrdm);
pwrdm->state_counter[pwrdm->state] = 1;
+ /* Initialize priority ordered list for wakeup latency constraint */
+ spin_lock_init(&pwrdm->wakeuplat_lock);
+ plist_head_init(&pwrdm->wakeuplat_dev_list, &pwrdm->wakeuplat_lock);
+
+ /* res_mutex protects res_list add and del ops */
+ mutex_init(&pwrdm->wakeuplat_mutex);
+
pr_debug("powerdomain: registered %s\n", pwrdm->name);
return 0;
@@ -208,6 +228,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
{
struct powerdomain **p = NULL;
+
if (!custom_funcs)
WARN(1, "powerdomain: No custom pwrdm functions registered\n");
else
@@ -383,6 +404,18 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
}
/**
+ * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
+ * @pwrdm: struct powerdomain *
+ *
+ * Return a pointer to the struct voltageomain that the specified powerdomain
+ * @pwrdm exists in.
+ */
+struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
+{
+ return pwrdm->voltdm.ptr;
+}
+
+/**
* pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
* @pwrdm: struct powerdomain *
*
@@ -935,16 +968,16 @@ int pwrdm_post_transition(void)
* @pwrdm: struct powerdomain * to wait for
*
* Context loss count is the sum of powerdomain off-mode counter, the
- * logic off counter and the per-bank memory off counter. Returns 0
+ * logic off counter and the per-bank memory off counter. Returns negative
* (and WARNs) upon error, otherwise, returns the context loss count.
*/
-u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
{
int i, count;
if (!pwrdm) {
WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
- return 0;
+ return -ENODEV;
}
count = pwrdm->state_counter[PWRDM_POWER_OFF];
@@ -953,7 +986,13 @@ u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
for (i = 0; i < pwrdm->banks; i++)
count += pwrdm->ret_mem_off_counter[i];
- pr_debug("powerdomain: %s: context loss count = %u\n",
+ /*
+ * Context loss count has to be a non-negative value. Clear the sign
+ * bit to get a value range from 0 to INT_MAX.
+ */
+ count &= INT_MAX;
+
+ pr_debug("powerdomain: %s: context loss count = %d\n",
pwrdm->name, count);
return count;
@@ -999,3 +1038,163 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
return 0;
}
+
+
+/**
+ * pwrdm_wakeuplat_set_constraint - Set powerdomain wakeup latency constraint
+ * @pwrdm: struct powerdomain * to which requesting device belongs to
+ * @dev: struct device * of requesting device
+ * @t: wakeup latency constraint in microseconds
+ *
+ * Adds new entry to powerdomain's wakeup latency constraint list.
+ * If the requesting device already exists in the list, old value is
+ * overwritten. Checks whether current power state is still adequate.
+ * Returns -EINVAL if the powerdomain or device pointer is NULL,
+ * or -ENOMEM if kmalloc fails, or -ERANGE if constraint can't be met,
+ * or returns 0 upon success.
+ */
+int pwrdm_wakeuplat_set_constraint (struct powerdomain *pwrdm,
+ struct device *dev, unsigned long t)
+{
+ struct wakeuplat_dev_list *user;
+ int found = 0, ret = 0;
+
+ if (!pwrdm || !dev) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&pwrdm->wakeuplat_mutex);
+
+ plist_for_each_entry(user, &pwrdm->wakeuplat_dev_list, node) {
+ if (user->dev == dev) {
+ found = 1;
+ break;
+ }
+ }
+
+ /* Add new entry to the list or update existing request */
+ if (found && user->constraint_us == t) {
+ goto exit_set;
+ } else if (!found) {
+ user = kzalloc(sizeof(struct wakeuplat_dev_list), GFP_KERNEL);
+ if (!user) {
+ pr_err("OMAP PM: FATAL ERROR: kzalloc failed\n");
+ ret = -ENOMEM;
+ goto exit_set;
+ }
+ user->dev = dev;
+ } else {
+ plist_del(&user->node, &pwrdm->wakeuplat_dev_list);
+ }
+
+ plist_node_init(&user->node, t);
+ plist_add(&user->node, &pwrdm->wakeuplat_dev_list);
+ user->node.prio = user->constraint_us = t;
+
+ ret = pwrdm_wakeuplat_update_pwrst(pwrdm);
+
+exit_set:
+ mutex_unlock(&pwrdm->wakeuplat_mutex);
+
+ return ret;
+}
+
+/**
+ * pwrdm_wakeuplat_release_constraint - Release powerdomain wkuplat constraint
+ * @pwrdm: struct powerdomain * to which requesting device belongs to
+ * @dev: struct device * of requesting device
+ *
+ * Removes device's entry from powerdomain's wakeup latency constraint list.
+ * Checks whether current power state is still adequate.
+ * Returns -EINVAL if the powerdomain or device pointer is NULL or
+ * no such entry exists in the list, or returns 0 upon success.
+ */
+int pwrdm_wakeuplat_release_constraint (struct powerdomain *pwrdm,
+ struct device *dev)
+{
+ struct wakeuplat_dev_list *user;
+ int found = 0, ret = 0;
+
+ if (!pwrdm || !dev) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&pwrdm->wakeuplat_mutex);
+
+ plist_for_each_entry(user, &pwrdm->wakeuplat_dev_list, node) {
+ if (user->dev == dev) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ pr_err("OMAP PM: Error: no prior constraint to release\n");
+ ret = -EINVAL;
+ goto exit_rls;
+ }
+
+ plist_del(&user->node, &pwrdm->wakeuplat_dev_list);
+ kfree(user);
+
+ ret = pwrdm_wakeuplat_update_pwrst(pwrdm);
+
+exit_rls:
+ mutex_unlock(&pwrdm->wakeuplat_mutex);
+
+ return ret;
+}
+
+/**
+ * pwrdm_wakeuplat_update_pwrst - Update power domain power state if needed
+ * @pwrdm: struct powerdomain * to which requesting device belongs to
+ *
+ * Finds minimum latency value from all entries in the list and
+ * the power domain power state neeting the constraint. Programs
+ * new state if it is different from current power state.
+ * Returns -EINVAL if the powerdomain or device pointer is NULL or
+ * no such entry exists in the list, or -ERANGE if constraint can't be met,
+ * or returns 0 upon success.
+ */
+int pwrdm_wakeuplat_update_pwrst(struct powerdomain *pwrdm)
+{
+ struct plist_node *node;
+ int ret = 0, new_state;
+ unsigned long min_latency = -1;
+
+ if (!plist_head_empty(&pwrdm->wakeuplat_dev_list)) {
+ node = plist_last(&pwrdm->wakeuplat_dev_list);
+ min_latency = node->prio;
+ }
+
+ /* Find power state with wakeup latency < minimum constraint. */
+ for (new_state = 0x0; new_state < PWRDM_MAX_PWRSTS; new_state++) {
+ if (min_latency == -1 ||
+ pwrdm->wakeup_lat[new_state] < min_latency)
+ break;
+ }
+
+ /* No power state wkuplat met constraint. Keep power domain ON. */
+ if (new_state == PWRDM_MAX_PWRSTS) {
+ new_state = PWRDM_FUNC_PWRST_ON;
+ ret = -ERANGE;
+ }
+
+ /* OSWR is not supported, set CSWR instead. TODO: add OSWR support */
+ if (new_state == PWRDM_FUNC_PWRST_OSWR)
+ new_state = PWRDM_FUNC_PWRST_CSWR;
+
+ if (pwrdm->state != new_state) {
+ if (cpu_is_omap44xx() || cpu_is_omap34xx())
+ omap_set_pwrdm_state(pwrdm, new_state);
+ }
+
+ pr_debug("OMAP PM: %s pwrst: curr= %d, prev= %d next= %d "
+ "wkuplat_min= %lu, state= %d\n", pwrdm->name,
+ pwrdm_read_pwrst(pwrdm), pwrdm_read_prev_pwrst(pwrdm),
+ pwrdm_read_next_pwrst(pwrdm), min_latency, new_state);
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index d23d979..12108f7 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -19,11 +19,16 @@
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/plist.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/atomic.h>
#include <plat/cpu.h>
+#include "voltage.h"
+
/* Powerdomain basic power states */
#define PWRDM_POWER_OFF 0x0
#define PWRDM_POWER_RET 0x1
@@ -43,6 +48,18 @@
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON)
+#define PWRSTS_RET_INA_ON ((1 << PWRDM_POWER_RET) | \
+ (1 << PWRDM_POWER_INACTIVE) | \
+ (1 << PWRDM_POWER_ON))
+
+#define PWRSTS_OFF_INA_ON ((1 << PWRDM_POWER_OFF) | \
+ (1 << PWRDM_POWER_INACTIVE) | \
+ (1 << PWRDM_POWER_ON))
+
+#define PWRSTS_OFF_RET_INA_ON ((1 << PWRDM_POWER_OFF) | \
+ (1 << PWRDM_POWER_RET) | \
+ (1 << PWRDM_POWER_INACTIVE) | \
+ (1 << PWRDM_POWER_ON))
/* Powerdomain flags */
#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */
@@ -72,12 +89,23 @@
/* XXX A completely arbitrary number. What is reasonable here? */
#define PWRDM_TRANSITION_BAILOUT 100000
+/* Powerdomain functional power states */
+#define PWRDM_FUNC_PWRST_OFF 0x0
+#define PWRDM_FUNC_PWRST_OSWR 0x1
+#define PWRDM_FUNC_PWRST_CSWR 0x2
+#define PWRDM_FUNC_PWRST_ON 0x3
+
+#define PWRDM_MAX_FUNC_PWRSTS 4
+
+#define UNSUP_STATE -1
+
struct clockdomain;
struct powerdomain;
/**
* struct powerdomain - OMAP powerdomain
* @name: Powerdomain name
+ * @voltdm: voltagedomain containing this powerdomain
* @omap_chip: represents the OMAP chip types containing this pwrdm
* @prcm_offs: the address offset from CM_BASE/PRM_BASE
* @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs
@@ -89,15 +117,22 @@ struct powerdomain;
* @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON
* @pwrdm_clkdms: Clockdomains in this powerdomain
* @node: list_head linking all powerdomains
+ * @voltdm_node: list_head linking all powerdomains in a voltagedomain
* @state:
* @state_counter:
* @timer:
* @state_timer:
- *
- * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
+ * @wakeup_lat: Wakeup latencies for possible powerdomain power states
+ * @wakeuplat_lock: spinlock for plist
+ * @wakeuplat_dev_list: plist_head linking all devices placing constraint
+ * @wa * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
*/
struct powerdomain {
const char *name;
+ union {
+ const char *name;
+ struct voltagedomain *ptr;
+ } voltdm;
const struct omap_chip_id omap_chip;
const s16 prcm_offs;
const u8 pwrsts;
@@ -109,6 +144,7 @@ struct powerdomain {
const u8 prcm_partition;
struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
struct list_head node;
+ struct list_head voltdm_node;
int state;
unsigned state_counter[PWRDM_MAX_PWRSTS];
unsigned ret_logic_off_counter;
@@ -118,6 +154,16 @@ struct powerdomain {
s64 timer;
s64 state_timer[PWRDM_MAX_PWRSTS];
#endif
+ const u32 wakeup_lat[PWRDM_MAX_FUNC_PWRSTS];
+ spinlock_t wakeuplat_lock;
+ struct plist_head wakeuplat_dev_list;
+ struct mutex wakeuplat_mutex;
+};
+
+struct wakeuplat_dev_list {
+ struct device *dev;
+ unsigned long constraint_us;
+ struct plist_node node;
};
/**
@@ -176,6 +222,7 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
int (*fn)(struct powerdomain *pwrdm,
struct clockdomain *clkdm));
+struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
@@ -207,7 +254,7 @@ int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
int pwrdm_pre_transition(void);
int pwrdm_post_transition(void);
int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
-u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
extern void omap2xxx_powerdomains_init(void);
@@ -226,5 +273,10 @@ extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);
extern struct powerdomain wkup_omap2_pwrdm;
extern struct powerdomain gfx_omap2_pwrdm;
+int pwrdm_wakeuplat_set_constraint(struct powerdomain *pwrdm,
+ struct device *dev, unsigned long t);
+int pwrdm_wakeuplat_release_constraint(struct powerdomain *pwrdm,
+ struct device *dev);
+int pwrdm_wakeuplat_update_pwrst(struct powerdomain *pwrdm);
#endif
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
index 4210c33..2242c8e 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -70,6 +70,7 @@ struct powerdomain gfx_omap2_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
struct powerdomain wkup_omap2_pwrdm = {
@@ -77,4 +78,5 @@ struct powerdomain wkup_omap2_pwrdm = {
.prcm_offs = WKUP_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_ON,
+ .voltdm = { .name = "wakeup" },
};
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c
index cc389fb..274f64c 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -38,6 +38,7 @@ static struct powerdomain dsp_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON,
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain mpu_24xx_pwrdm = {
@@ -53,6 +54,7 @@ static struct powerdomain mpu_24xx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON,
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain core_24xx_pwrdm = {
@@ -71,6 +73,7 @@ static struct powerdomain core_24xx_pwrdm = {
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
[2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
},
+ .voltdm = { .name = "core" },
};
@@ -95,6 +98,7 @@ static struct powerdomain mdm_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
#endif /* CONFIG_SOC_OMAP2430 */
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 469a920..b91224b 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -52,6 +52,13 @@ static struct powerdomain iva2_pwrdm = {
[2] = PWRSTS_OFF_ON,
[3] = PWRSTS_ON,
},
+ .voltdm = { .name = "mpu_iva" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1100,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 350,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain mpu_3xxx_pwrdm = {
@@ -68,6 +75,13 @@ static struct powerdomain mpu_3xxx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_OFF_ON,
},
+ .voltdm = { .name = "mpu_iva" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 95,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 45,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/*
@@ -98,6 +112,13 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 100,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 60,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain core_3xxx_es3_1_pwrdm = {
@@ -121,6 +142,13 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 100,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 60,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain dss_pwrdm = {
@@ -136,6 +164,13 @@ static struct powerdomain dss_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 70,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 20,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/*
@@ -157,6 +192,13 @@ static struct powerdomain sgx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain cam_pwrdm = {
@@ -172,6 +214,13 @@ static struct powerdomain cam_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 850,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 35,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain per_pwrdm = {
@@ -187,12 +236,20 @@ static struct powerdomain per_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 200,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 110,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain emu_pwrdm = {
.name = "emu_pwrdm",
.prcm_offs = OMAP3430_EMU_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "core" },
};
static struct powerdomain neon_pwrdm = {
@@ -201,6 +258,13 @@ static struct powerdomain neon_pwrdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
+ .voltdm = { .name = "mpu_iva" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 200,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 35,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain usbhost_pwrdm = {
@@ -223,36 +287,48 @@ static struct powerdomain usbhost_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 800,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 150,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
static struct powerdomain dpll1_pwrdm = {
.name = "dpll1_pwrdm",
.prcm_offs = MPU_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "mpu_iva" },
};
static struct powerdomain dpll2_pwrdm = {
.name = "dpll2_pwrdm",
.prcm_offs = OMAP3430_IVA2_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "mpu_iva" },
};
static struct powerdomain dpll3_pwrdm = {
.name = "dpll3_pwrdm",
.prcm_offs = PLL_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "core" },
};
static struct powerdomain dpll4_pwrdm = {
.name = "dpll4_pwrdm",
.prcm_offs = PLL_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "core" },
};
static struct powerdomain dpll5_pwrdm = {
.name = "dpll5_pwrdm",
.prcm_offs = PLL_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+ .voltdm = { .name = "core" },
};
/* As powerdomains are added or removed above, this list must also be changed */
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index c4222c7..ec24a39 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -1,7 +1,7 @@
/*
* OMAP4 Power domains framework
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Texas Instruments, Inc.
* Copyright (C) 2009-2011 Nokia Corporation
*
* Abhijit Pagare (abhijitpagare@ti.com)
@@ -33,10 +33,11 @@
/* core_44xx_pwrdm: CORE power domain */
static struct powerdomain core_44xx_pwrdm = {
.name = "core_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_CORE_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 5,
.pwrsts_mem_ret = {
@@ -54,15 +55,22 @@ static struct powerdomain core_44xx_pwrdm = {
[4] = PWRSTS_ON, /* ducati_unicache */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* gfx_44xx_pwrdm: 3D accelerator power domain */
static struct powerdomain gfx_44xx_pwrdm = {
.name = "gfx_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_GFX_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_INA_ON,
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF, /* gfx_mem */
@@ -71,15 +79,22 @@ static struct powerdomain gfx_44xx_pwrdm = {
[0] = PWRSTS_ON, /* gfx_mem */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* abe_44xx_pwrdm: Audio back end power domain */
static struct powerdomain abe_44xx_pwrdm = {
.name = "abe_pwrdm",
+ .voltdm = { .name = "iva" },
.prcm_offs = OMAP4430_PRM_ABE_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
.banks = 2,
.pwrsts_mem_ret = {
@@ -91,15 +106,22 @@ static struct powerdomain abe_44xx_pwrdm = {
[1] = PWRSTS_ON, /* periphmem */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* dss_44xx_pwrdm: Display subsystem power domain */
static struct powerdomain dss_44xx_pwrdm = {
.name = "dss_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_DSS_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
.banks = 1,
.pwrsts_mem_ret = {
@@ -109,15 +131,22 @@ static struct powerdomain dss_44xx_pwrdm = {
[0] = PWRSTS_ON, /* dss_mem */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* tesla_44xx_pwrdm: Tesla processor power domain */
static struct powerdomain tesla_44xx_pwrdm = {
.name = "tesla_pwrdm",
+ .voltdm = { .name = "iva" },
.prcm_offs = OMAP4430_PRM_TESLA_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 3,
.pwrsts_mem_ret = {
@@ -131,14 +160,21 @@ static struct powerdomain tesla_44xx_pwrdm = {
[2] = PWRSTS_ON, /* tesla_l2 */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* wkup_44xx_pwrdm: Wake-up power domain */
static struct powerdomain wkup_44xx_pwrdm = {
.name = "wkup_pwrdm",
+ .voltdm = { .name = "wakeup" },
.prcm_offs = OMAP4430_PRM_WKUP_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
.pwrsts = PWRSTS_ON,
.banks = 1,
.pwrsts_mem_ret = {
@@ -152,10 +188,11 @@ static struct powerdomain wkup_44xx_pwrdm = {
/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
static struct powerdomain cpu0_44xx_pwrdm = {
.name = "cpu0_pwrdm",
+ .voltdm = { .name = "mpu" },
.prcm_offs = OMAP4430_PRCM_MPU_CPU0_INST,
.prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -164,15 +201,22 @@ static struct powerdomain cpu0_44xx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* cpu0_l1 */
},
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
static struct powerdomain cpu1_44xx_pwrdm = {
.name = "cpu1_pwrdm",
+ .voltdm = { .name = "mpu" },
.prcm_offs = OMAP4430_PRCM_MPU_CPU1_INST,
.prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -181,14 +225,21 @@ static struct powerdomain cpu1_44xx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* cpu1_l1 */
},
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* emu_44xx_pwrdm: Emulation power domain */
static struct powerdomain emu_44xx_pwrdm = {
.name = "emu_pwrdm",
+ .voltdm = { .name = "wakeup" },
.prcm_offs = OMAP4430_PRM_EMU_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
.pwrsts_mem_ret = {
@@ -200,12 +251,13 @@ static struct powerdomain emu_44xx_pwrdm = {
};
/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */
-static struct powerdomain mpu_44xx_pwrdm = {
+static struct powerdomain mpu_443x_pwrdm = {
.name = "mpu_pwrdm",
+ .voltdm = { .name = "mpu" },
.prcm_offs = OMAP4430_PRM_MPU_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP443X),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 3,
.pwrsts_mem_ret = {
@@ -218,15 +270,47 @@ static struct powerdomain mpu_44xx_pwrdm = {
[1] = PWRSTS_ON, /* mpu_l2 */
[2] = PWRSTS_ON, /* mpu_ram */
},
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
+};
+
+static struct powerdomain mpu_446x_pwrdm = {
+ .name = "mpu_pwrdm",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP4430_PRM_MPU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
+ .pwrsts = PWRSTS_RET_INA_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [1] = PWRSTS_RET, /* mpu_ram */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* mpu_l2 */
+ [1] = PWRSTS_ON, /* mpu_ram */
+ },
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* ivahd_44xx_pwrdm: IVA-HD power domain */
static struct powerdomain ivahd_44xx_pwrdm = {
.name = "ivahd_pwrdm",
+ .voltdm = { .name = "iva" },
.prcm_offs = OMAP4430_PRM_IVAHD_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
.banks = 4,
.pwrsts_mem_ret = {
@@ -242,15 +326,22 @@ static struct powerdomain ivahd_44xx_pwrdm = {
[3] = PWRSTS_ON, /* tcm2_mem */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* cam_44xx_pwrdm: Camera subsystem power domain */
static struct powerdomain cam_44xx_pwrdm = {
.name = "cam_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_CAM_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_INA_ON,
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF, /* cam_mem */
@@ -259,15 +350,22 @@ static struct powerdomain cam_44xx_pwrdm = {
[0] = PWRSTS_ON, /* cam_mem */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* l3init_44xx_pwrdm: L3 initators pheripherals power domain */
static struct powerdomain l3init_44xx_pwrdm = {
.name = "l3init_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_L3INIT_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -277,15 +375,22 @@ static struct powerdomain l3init_44xx_pwrdm = {
[0] = PWRSTS_ON, /* l3init_bank1 */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = 1000,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/* l4per_44xx_pwrdm: Target peripherals power domain */
static struct powerdomain l4per_44xx_pwrdm = {
.name = "l4per_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_L4PER_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_RET_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 2,
.pwrsts_mem_ret = {
@@ -297,6 +402,12 @@ static struct powerdomain l4per_44xx_pwrdm = {
[1] = PWRSTS_ON, /* retained_bank */
},
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .wakeup_lat = {
+ [PWRDM_FUNC_PWRST_OFF] = UNSUP_STATE,
+ [PWRDM_FUNC_PWRST_OSWR] = 600,
+ [PWRDM_FUNC_PWRST_CSWR] = 300,
+ [PWRDM_FUNC_PWRST_ON] = 0,
+ },
};
/*
@@ -305,19 +416,21 @@ static struct powerdomain l4per_44xx_pwrdm = {
*/
static struct powerdomain always_on_core_44xx_pwrdm = {
.name = "always_on_core_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_ALWAYS_ON_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
.pwrsts = PWRSTS_ON,
};
/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
static struct powerdomain cefuse_44xx_pwrdm = {
.name = "cefuse_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_CEFUSE_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_ON,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
+ .pwrsts = PWRSTS_OFF_INA_ON,
};
/*
@@ -339,7 +452,8 @@ static struct powerdomain *powerdomains_omap44xx[] __initdata = {
&cpu0_44xx_pwrdm,
&cpu1_44xx_pwrdm,
&emu_44xx_pwrdm,
- &mpu_44xx_pwrdm,
+ &mpu_443x_pwrdm,
+ &mpu_446x_pwrdm,
&ivahd_44xx_pwrdm,
&cam_44xx_pwrdm,
&l3init_44xx_pwrdm,
diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h
index 6d2776f..175412a 100644
--- a/arch/arm/mach-omap2/prm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -1,7 +1,7 @@
/*
* OMAP44xx Power Management register bits
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Texas Instruments, Inc.
* Copyright (C) 2009-2010 Nokia Corporation
*
* Paul Walmsley (paul@pwsan.com)
@@ -283,6 +283,14 @@
#define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT 10
#define OMAP4430_DUCATI_UNICACHE_STATEST_MASK (0x3 << 10)
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP4460_EMIF1_OFFWKUP_DISABLE_SHIFT 8
+#define OMAP4460_EMIF1_OFFWKUP_DISABLE_MASK (1 << 8)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP4460_EMIF2_OFFWKUP_DISABLE_SHIFT 9
+#define OMAP4460_EMIF2_OFFWKUP_DISABLE_MASK (1 << 9)
+
/* Used by RM_MPU_RSTST */
#define OMAP4430_EMULATION_RST_SHIFT 0
#define OMAP4430_EMULATION_RST_MASK (1 << 0)
@@ -1063,6 +1071,14 @@
#define OMAP4430_SCLL_SHIFT 8
#define OMAP4430_SCLL_MASK (0xff << 8)
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_HSCLH_SHIFT 16
+#define OMAP4430_HSCLH_MASK (0xff << 16)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_HSCLL_SHIFT 24
+#define OMAP4430_HSCLL_MASK (0xff << 24)
+
/* Used by PRM_RSTST */
#define OMAP4430_SECURE_WDT_RST_SHIFT 4
#define OMAP4430_SECURE_WDT_RST_MASK (1 << 4)
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 051213f..3b83763 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -20,6 +20,8 @@
#include <plat/cpu.h>
#include <plat/prcm.h>
+#include "vp.h"
+
#include "prm2xxx_3xxx.h"
#include "cm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
@@ -156,3 +158,57 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
+
+/* PRM VP */
+
+/*
+ * struct omap3_vp - OMAP3 VP register access description.
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ */
+struct omap3_vp {
+ u32 tranxdone_status;
+};
+
+struct omap3_vp omap3_vp[] = {
+ [OMAP3_VP_VDD_MPU_ID] = {
+ .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+ },
+ [OMAP3_VP_VDD_CORE_ID] = {
+ .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
+ },
+};
+
+#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
+
+u32 omap3_prm_vp_check_txdone(u8 vp_id)
+{
+ struct omap3_vp *vp = &omap3_vp[vp_id];
+ u32 irqstatus;
+
+ irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ return irqstatus & vp->tranxdone_status;
+}
+
+void omap3_prm_vp_clear_txdone(u8 vp_id)
+{
+ struct omap3_vp *vp = &omap3_vp[vp_id];
+
+ omap2_prm_write_mod_reg(vp->tranxdone_status,
+ OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+}
+
+u32 omap3_prm_vcvp_read(u8 offset)
+{
+ return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
+}
+
+void omap3_prm_vcvp_write(u32 val, u8 offset)
+{
+ omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
+}
+
+u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+{
+ return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
+}
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index a1fc62a..cef533d 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -303,7 +303,19 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
+/* OMAP3-specific VP functions */
+u32 omap3_prm_vp_check_txdone(u8 vp_id);
+void omap3_prm_vp_clear_txdone(u8 vp_id);
+
+/*
+ * OMAP3 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap3_prm_vcvp_read(u8 offset);
+extern void omap3_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
#endif /* CONFIG_ARCH_OMAP4 */
+
#endif
/*
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index a2a04bf..8a3bba3 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -21,8 +21,11 @@
#include <plat/cpu.h>
#include <plat/prcm.h>
+#include "vp.h"
#include "prm44xx.h"
#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
/*
* Address offset (in bytes) between the reset control and the reset
@@ -193,3 +196,71 @@ void omap4_prm_global_warm_sw_reset(void)
v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
OMAP4_RM_RSTCTRL);
}
+
+/* PRM VP */
+
+/*
+ * struct omap4_vp - OMAP4 VP register access description.
+ * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ */
+struct omap4_vp {
+ u32 irqstatus_mpu;
+ u32 tranxdone_status;
+};
+
+static struct omap4_vp omap4_vp[] = {
+ [OMAP4_VP_VDD_MPU_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
+ .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
+ },
+ [OMAP4_VP_VDD_IVA_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
+ },
+ [OMAP4_VP_VDD_CORE_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
+ },
+};
+
+u32 omap4_prm_vp_check_txdone(u8 vp_id)
+{
+ struct omap4_vp *vp = &omap4_vp[vp_id];
+ u32 irqstatus;
+
+ irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ vp->irqstatus_mpu);
+ return irqstatus & vp->tranxdone_status;
+}
+
+void omap4_prm_vp_clear_txdone(u8 vp_id)
+{
+ struct omap4_vp *vp = &omap4_vp[vp_id];
+
+ omap4_prminst_write_inst_reg(vp->tranxdone_status,
+ OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ vp->irqstatus_mpu);
+};
+
+u32 omap4_prm_vcvp_read(u8 offset)
+{
+ return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST, offset);
+}
+
+void omap4_prm_vcvp_write(u32 val, u8 offset)
+{
+ omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST, offset);
+}
+
+u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+{
+ return omap4_prminst_rmw_inst_reg_bits(mask, bits,
+ OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ offset);
+}
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 67a0d3f..026529f 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -713,8 +713,8 @@
#define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a0)
#define OMAP4_PRM_VC_CFG_CHANNEL_OFFSET 0x00a4
#define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a4)
-#define OMAP4_PRM_VC_CFG_I2C_INSTE_OFFSET 0x00a8
-#define OMAP4430_PRM_VC_CFG_I2C_INSTE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a8)
+#define OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET 0x00a8
+#define OMAP4430_PRM_VC_CFG_I2C_MODE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a8)
#define OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET 0x00ac
#define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ac)
#define OMAP4_PRM_SRAM_COUNT_OFFSET 0x00b0
@@ -773,6 +773,18 @@ extern int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
extern void omap4_prm_global_warm_sw_reset(void);
+/* OMAP4-specific VP functions */
+u32 omap4_prm_vp_check_txdone(u8 vp_id);
+void omap4_prm_vp_clear_txdone(u8 vp_id);
+
+/*
+ * OMAP4 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap4_prm_vcvp_read(u8 offset);
+extern void omap4_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
+
# endif
#endif
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 1ac361b..3c1564d 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -57,9 +57,9 @@
* NOTE: By default the serial timeout is disabled as it causes lost characters
* over the serial ports. This means that the UART clocks will stay on until
* disabled via sysfs. This also causes that any deeper omap sleep states are
- * blocked.
+ * blocked.
*/
-#define DEFAULT_TIMEOUT 0
+#define DEFAULT_TIMEOUT 1000
#define MAX_UART_HWMOD_NAME_LEN 16
@@ -315,6 +315,12 @@ static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
v |= OMAP3_PADCONF_WAKEUPENABLE0;
omap_ctrl_writew(v, uart->padconf);
}
+
+ if (cpu_is_omap44xx() && uart->padconf) {
+ u16 v = omap4_ctrl_pad_readw(uart->padconf);
+ v |= OMAP44XX_PADCONF_WAKEUPENABLE0;
+ omap4_ctrl_pad_writew(v, uart->padconf);
+ }
}
static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
@@ -347,7 +353,7 @@ static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
if (uart->dma_enabled)
idlemode = HWMOD_IDLEMODE_FORCE;
else
- idlemode = HWMOD_IDLEMODE_SMART;
+ idlemode = HWMOD_IDLEMODE_SMART_WKUP;
} else {
idlemode = HWMOD_IDLEMODE_NO;
}
@@ -418,8 +424,9 @@ void omap_uart_resume_idle(int num)
}
/* Check for normal UART wakeup */
- if (__raw_readl(uart->wk_st) & uart->wk_mask)
- omap_uart_block_sleep(uart);
+ if (uart->wk_st && uart->wk_mask)
+ if (__raw_readl(uart->wk_st) & uart->wk_mask)
+ omap_uart_block_sleep(uart);
return;
}
}
@@ -447,6 +454,10 @@ int omap_uart_can_sleep(void)
can_sleep = 0;
continue;
}
+ if(omap_uart_active(uart->num, uart->timeout)) {
+ can_sleep = 0;
+ continue;
+ }
/* This UART can now safely sleep. */
omap_uart_allow_sleep(uart);
@@ -543,7 +554,20 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
uart->wk_en = NULL;
uart->wk_st = NULL;
uart->wk_mask = 0;
- uart->padconf = 0;
+ switch (uart->num) {
+ case 0:
+ uart->padconf = 0x0E4;
+ break;
+ case 1:
+ uart->padconf = 0x11C;
+ break;
+ case 2:
+ uart->padconf = 0x144;
+ break;
+ case 3:
+ uart->padconf = 0x15C;
+ break;
+ }
}
uart->irqflags |= IRQF_SHARED;
@@ -843,7 +867,8 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
console_unlock();
- if ((cpu_is_omap34xx() && uart->padconf) ||
+ if (((cpu_is_omap34xx() || cpu_is_omap44xx())
+ && uart->padconf) ||
(uart->wk_en && uart->wk_mask)) {
device_init_wakeup(&od->pdev.dev, true);
DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout);
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
new file mode 100644
index 0000000..c8ea819
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -0,0 +1,486 @@
+/*
+ * OMAP44xx CPU low power powerdown and powerup code.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.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/linkage.h>
+#include <asm/system.h>
+#include <asm/smp_scu.h>
+#include <asm/memory.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <plat/omap44xx.h>
+#include <mach/omap4-common.h>
+
+#include "omap4-sar-layout.h"
+
+#ifdef CONFIG_SMP
+
+/* Masks used for MMU manipulation */
+#define TTRBIT_MASK 0xffffc000
+#define TABLE_INDEX_MASK 0xfff00000
+#define TABLE_ENTRY 0x00000c02
+#define CACHE_DISABLE_MASK 0xffffe7fb
+#define TABLE_ADDRESS_OFFSET 0x04
+#define CR_VALUE_OFFSET 0x08
+#define SCU_POWER_SECURE_INDEX 0x108
+
+/*
+ * =============================
+ * == CPU suspend entry point ==
+ * =============================
+ *
+ * void omap4_cpu_suspend(unsigned int cpu, unsigned int save_state)
+ *
+ * This function code saves the CPU context and performs the CPU
+ * power down sequence. Calling WFI effectively changes the CPU
+ * power domains states to the desired target power state.
+ *
+ * @cpu : contains cpu id (r0)
+ * @save_state : contains context save state (r1)
+ * 0 - No context lost
+ * 1 - CPUx L1 and logic lost: MPUSS CSWR
+ * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
+ * @return: This function never returns for CPU OFF and DORMANT power states.
+ * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
+ * from this follows a full CPU reset path via ROM code to CPU restore code.
+ * It returns to the caller for CPU INACTIVE and ON power states or in case
+ * CPU failed to transition to targeted OFF/DORMANT state.
+ */
+
+ENTRY(omap4_cpu_suspend)
+ stmfd sp!, {r0-r12, lr} @ Save registers on stack
+ cmp r1, #0x0
+ beq do_WFI @ Nothing to save, jump to WFI
+ mov r5, r0
+ mov r6, r1
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ str r6, [r8, #L2X0_OFFSET] @ Store save state
+ ands r5, r5, #0x0f
+ orreq r8, r8, #CPU0_SAVE_OFFSET
+ orrne r8, r8, #CPU1_SAVE_OFFSET
+
+ /*
+ * Save only needed CPU CP15 registers. VFP, breakpoint,
+ * performance monitor registers are not saved. Generic
+ * code suppose to take care of those.
+ */
+ mov r4, sp @ Store sp
+ mrs r5, spsr @ Store spsr
+ mov r6, lr @ Store lr
+ stmia r8!, {r4-r6}
+
+ /* c1 and c2 registers */
+ mrc p15, 0, r4, c1, c0, 2 @ CPACR
+ mrc p15, 0, r5, c2, c0, 0 @ TTBR0
+ mrc p15, 0, r6, c2, c0, 1 @ TTBR1
+ mrc p15, 0, r7, c2, c0, 2 @ TTBCR
+ stmia r8!, {r4-r7}
+
+ /* c3 and c10 registers */
+ mrc p15, 0, r4, c3, c0, 0 @ DACR
+ mrc p15, 0, r5, c10, c2, 0 @ PRRR
+ mrc p15, 0, r6, c10, c2, 1 @ NMRR
+ stmia r8!,{r4-r6}
+
+ /* c12, c13 and CPSR registers */
+ mrc p15, 0, r4, c13, c0, 1 @ Context ID
+ mrc p15, 0, r5, c13, c0, 2 @ User r/w thread ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS VBAR
+ mrs r7, cpsr @ Store CPSR
+ stmia r8!, {r4-r7}
+
+ /* c1 control register */
+ mrc p15, 0, r4, c1, c0, 0 @ Save control register
+ stmia r8!, {r4}
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ bl v7_flush_dcache_all
+
+ /*
+ * Clear the SCTLR.C bit to prevent further data cache
+ * allocation. Clearing SCTLR.C would make all the data accesses
+ * strongly ordered and would not hit the cache.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Invalidate L1 data cache. Even though only invalidate is
+ * necessary exported flush API is used here. Doing clean
+ * on already clean cache would be almost NOP.
+ */
+ bl v7_flush_dcache_all
+
+ /*
+ * Switch the CPU from Symmetric Multiprocessing (SMP) mode
+ * to AsymmetricMultiprocessing (AMP) mode by programming
+ * the SCU power status to DORMANT or OFF mode.
+ * This enables the CPU to be taken out of coherency by
+ * preventing the CPU from receiving cache, TLB, or BTB
+ * maintenance operations broadcast by other CPUs in the cluster.
+ */
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ ldr r9, [r8, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne scu_gp_set
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ ldreq r0, [r8, #SCU_OFFSET0]
+ ldreq r1, [r8, #L1_OFFSET0]
+ ldrne r0, [r8, #SCU_OFFSET1]
+ ldrne r1, [r8, #L1_OFFSET0]
+ stmfd r13!, {r4-r12, r14}
+ ldr r12, =SCU_POWER_SECURE_INDEX
+ dsb
+ smc #0
+ dsb
+ ldmfd r13!, {r4-r12, r14}
+ b skip_scu_gp_set
+scu_gp_set:
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ ldreq r1, [r8, #SCU_OFFSET0]
+ ldrne r1, [r8, #SCU_OFFSET1]
+ bl omap4_get_scu_base
+ bl scu_power_mode
+skip_scu_gp_set:
+ isb
+ dsb
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Clean and invalidate the L2 cache.
+ * Common cache-l2x0.c functions can't be used here since it
+ * uses spinlocks. We are out of coherency here with data cache
+ * disabled. The spinlock implementation uses exclusive load/store
+ * instruction which can fail without data cache being enabled.
+ * OMAP4 hardware doesn't support exclusive monitor which can
+ * overcome exclusive access issue. Because of this, CPU can
+ * lead to deadlock.
+ */
+l2x_clean_inv:
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ ldr r0, [r8, #L2X0_OFFSET]
+ cmp r0, #3
+ bne do_WFI
+#ifdef CONFIG_PL310_ERRATA_727915
+ mov r0, #0x03
+ mov r12, #0x100
+ dsb
+ smc #0
+ dsb
+#endif
+ bl omap4_get_l2cache_base
+ mov r2, r0
+ mov r0, #0xff
+ str r0, [r2, #L2X0_CLEAN_WAY]
+wait:
+ ldr r0, [r2, #L2X0_CLEAN_WAY]
+ ands r0, r0, #0xff
+ bne wait
+#ifdef CONFIG_PL310_ERRATA_727915
+ mov r0, #0x00
+ mov r12, #0x100
+ dsb
+ smc #0
+ dsb
+#endif
+#endif
+
+do_WFI:
+#ifdef CONFIG_CACHE_L2X0
+ /* Issue cache sync before WFI to drain L2X0 buffer */
+l2x_sync:
+ bl omap4_get_l2cache_base
+ mov r2, r0
+ mov r0, #0x0
+ str r0, [r2, #L2X0_CACHE_SYNC]
+sync:
+ ldr r0, [r2, #L2X0_CACHE_SYNC]
+ ands r0, r0, #0x1
+ bne sync
+#endif
+ /*
+ * Execute an ISB instruction to ensure that all of the
+ * CP15 register changes have been committed.
+ */
+ isb
+
+ /*
+ * Execute a barrier instruction to ensure that all cache,
+ * TLB and branch predictor maintenance operations issued
+ * by any CPU in the cluster have completed.
+ */
+ dsb
+ dmb
+
+ /*
+ * Execute a WFI instruction and wait until the
+ * STANDBYWFI output is asserted to indicate that the
+ * CPU is in idle and low power state. CPU can specualatively
+ * prefetch the instructions so add NOPs after WFI. Sixteen
+ * NOPs as per Cortex-A9 pipeline.
+ */
+ wfi @ Wait For Interrupt
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /*
+ * CPU is here when it failed to enter OFF/DORMANT or
+ * no low power state was attempted.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ tst r0, #(1 << 2) @ Check C bit enabled?
+ orreq r0, r0, #(1 << 2) @ Enable the C bit
+ mcreq p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Ensure the CPU power state is set to NORMAL in
+ * SCU power state so that CPU is back in coherency.
+ * In non-coherent mode CPU can lock-up and lead to
+ * system deadlock.
+ */
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ ldr r9, [r8, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne scu_gp_clear
+ mov r0, #SCU_PM_NORMAL
+ mov r1, #0x00
+ stmfd r13!, {r4-r12, r14}
+ ldr r12, =SCU_POWER_SECURE_INDEX
+ dsb
+ smc #0
+ dsb
+ ldmfd r13!, {r4-r12, r14}
+ b skip_scu_gp_clear
+scu_gp_clear:
+ bl omap4_get_scu_base
+ mov r1, #SCU_PM_NORMAL
+ bl scu_power_mode
+skip_scu_gp_clear:
+ isb
+ dsb
+
+ ldmfd sp!, {r0-r12, pc} @ Restore regs and return
+ENDPROC(omap4_cpu_suspend)
+
+/*
+ * ============================
+ * == CPU resume entry point ==
+ * ============================
+ *
+ * void omap4_cpu_resume(void)
+ *
+ * ROM code jumps to this function while waking up from CPU
+ * OFF or DORMANT state. Physical address of the function is
+ * stored in the SAR RAM while entering to OFF or DORMANT mode.
+ */
+
+ENTRY(omap4_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Restore the L2 AUXCTRL and enable the L2 cache.
+ * 0x109 = Program the L2X0 AUXCTRL
+ * 0x102 = Enable the L2 using L2X0 CTRL
+ * register r0 contains value to be programmed.
+ * L2 cache is already invalidate by ROM code as part
+ * of MPUSS OFF wakeup path.
+ */
+ ldr r2, =OMAP44XX_L2CACHE_BASE
+ ldr r0, [r2, #L2X0_CTRL]
+ and r0, #0x0f
+ cmp r0, #1
+ beq skip_l2en @ Skip if already enabled
+ ldr r3, =OMAP44XX_SAR_RAM_BASE
+ ldr r0, [r3, #L2X0_AUXCTRL_OFFSET]
+ ldr r12, =0x109 @ Setup L2 AUXCTRL value
+ dsb
+ smc #0
+ dsb
+ mov r0, #0x1
+ ldr r12, =0x102 @ Enable L2 Cache controller
+ dsb
+ smc #0
+ dsb
+skip_l2en:
+#endif
+
+ /*
+ * Check the wakeup cpuid and use appropriate
+ * SAR BANK location for context restore.
+ */
+ ldr r3, =OMAP44XX_SAR_RAM_BASE
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 0 @ Invalidate L1 I
+ mrc p15, 0, r0, c0, c0, 5 @ MPIDR
+ ands r0, r0, #0x0f
+ orreq r3, r3, #CPU0_SAVE_OFFSET
+ orrne r3, r3, #CPU1_SAVE_OFFSET
+
+ /* Restore cp15 registers */
+ ldmia r3!, {r4-r6}
+ mov sp, r4 @ Restore sp
+ msr spsr_cxsf, r5 @ Restore spsr
+ mov lr, r6 @ Restore lr
+
+ /* c1 and c2 registers */
+ ldmia r3!, {r4-r7}
+ mcr p15, 0, r4, c1, c0, 2 @ CPACR
+ mcr p15, 0, r5, c2, c0, 0 @ TTBR0
+ mcr p15, 0, r6, c2, c0, 1 @ TTBR1
+ mcr p15, 0, r7, c2, c0, 2 @ TTBCR
+
+ /* c3 and c10 registers */
+ ldmia r3!,{r4-r6}
+ mcr p15, 0, r4, c3, c0, 0 @ DACR
+ mcr p15, 0, r5, c10, c2, 0 @ PRRR
+ mcr p15, 0, r6, c10, c2, 1 @ NMRR
+
+ /* c12, c13 and CPSR registers */
+ ldmia r3!,{r4-r7}
+ mcr p15, 0, r4, c13, c0, 1 @ Context ID
+ mcr p15, 0, r5, c13, c0, 2 @ User r/w thread ID
+ mcr p15, 0, r6, c12, c0, 0 @ Secure or NS VBAR
+ msr cpsr, r7 @ store cpsr
+
+ /*
+ * Enabling MMU here. Page entry needs to be altered
+ * to create temporary 1:1 map and then resore the entry
+ * ones MMU is enabled
+ */
+ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
+ and r7, #0x7 @ Extract N (0:2) to decide
+ cmp r7, #0x0 @ TTBR0/TTBR1
+ beq use_ttbr0
+ttbr_error:
+ b ttbr_error @ Only N = 0 supported
+use_ttbr0:
+ mrc p15, 0, r2, c2, c0, 0 @ Read TTBR0
+ ldr r5, =TTRBIT_MASK
+ and r2, r5
+ mov r4, pc
+ ldr r5, =TABLE_INDEX_MASK
+ and r4, r5 @ r4 = 31 to 20 bits of pc
+ ldr r1, =TABLE_ENTRY
+ add r1, r1, r4 @ r1 has value of table entry
+ lsr r4, #18 @ Address of table entry
+ add r2, r4 @ r2 - location to be modified
+
+ /* Ensure the modified entry makes it to main memory */
+#ifdef CONFIG_CACHE_L2X0
+ ldr r5, =OMAP44XX_L2CACHE_BASE
+ str r2, [r5, #L2X0_CLEAN_INV_LINE_PA]
+wait_l2:
+ ldr r0, [r5, #L2X0_CLEAN_INV_LINE_PA]
+ ands r0, #1
+ bne wait_l2
+#endif
+
+ /* Storing previous entry of location being modified */
+ ldr r5, =OMAP44XX_SAR_RAM_BASE
+ ldr r4, [r2]
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ streq r4, [r5, #MMU_OFFSET0] @ Modify the table entry
+ strne r4, [r5, #MMU_OFFSET1]
+ str r1, [r2]
+
+ /*
+ * Storing address of entry being modified
+ * It will be restored after enabling MMU
+ */
+ ldr r5, =OMAP44XX_SAR_RAM_BASE
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ orreq r5, r5, #MMU_OFFSET0
+ orrne r5, r5, #MMU_OFFSET1
+ str r2, [r5, #TABLE_ADDRESS_OFFSET]
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB
+ mcr p15, 0, r0, c8, c5, 0 @ Invalidate ITLB
+ mcr p15, 0, r0, c8, c6, 0 @ Invalidate DTLB
+
+ /*
+ * Restore control register but don't enable Data caches here.
+ * Caches will be enabled after restoring MMU table entry.
+ */
+ ldmia r3!, {r4}
+ str r4, [r5, #CR_VALUE_OFFSET] @ Store previous value of CR
+ ldr r2, =CACHE_DISABLE_MASK
+ and r4, r2
+ mcr p15, 0, r4, c1, c0, 0
+ isb
+ dsb
+ ldr r0, =mmu_on_label
+ bx r0
+mmu_on_label:
+ /* Set up the per-CPU stacks */
+ bl cpu_init
+
+ /*
+ * Restore the MMU table entry that was modified for
+ * enabling MMU.
+ */
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ orreq r8, r8, #MMU_OFFSET0 @ Get address of entry that..
+ orrne r8, r8, #MMU_OFFSET1 @ was modified
+ ldr r2, [r8, #TABLE_ADDRESS_OFFSET]
+ ldr r3, =local_va2pa_offet
+ add r2, r2, r3
+ ldr r0, [r8] @ Get the previous value..
+ str r0, [r2] @ which needs to be restored
+ mov r0, #0
+ mcr p15, 0, r0, c7, c1, 6 @ flush TLB and issue barriers
+ mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB
+ mcr p15, 0, r0, c8, c5, 0 @ Invalidate ITLB
+ mcr p15, 0, r0, c8, c6, 0 @ Invalidate DTLB
+ dsb
+ isb
+ ldr r0, [r8, #CR_VALUE_OFFSET] @ Restore the Control register
+ mcr p15, 0, r0, c1, c0, 0 @ with caches enabled.
+ isb
+
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+ .equ local_va2pa_offet, (PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
+ENDPROC(omap4_cpu_resume)
+
+#endif
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index f438cf4..4eac1bc 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -32,7 +32,7 @@ static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
omap_vp_disable(voltdm);
sr_disable(voltdm);
if (is_volt_reset)
- omap_voltage_reset(voltdm);
+ voltdm_reset(voltdm);
return 0;
}
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index fb7dc52..f8c6305 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -62,6 +62,7 @@ static LIST_HEAD(sr_list);
static struct omap_sr_class_data *sr_class;
static struct omap_sr_pmic_data *sr_pmic_data;
+static struct dentry *sr_dbg_dir;
static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
{
@@ -143,7 +144,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
sr_write_reg(sr_info, IRQSTATUS, status);
}
- if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
+ if (sr_class->notify)
sr_class->notify(sr_info->voltdm, status);
return IRQ_HANDLED;
@@ -258,9 +259,7 @@ static int sr_late_init(struct omap_sr *sr_info)
struct resource *mem;
int ret = 0;
- if (sr_class->class_type == SR_CLASS2 &&
- sr_class->notify_flags && sr_info->irq) {
-
+ if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
if (name == NULL) {
ret = -ENOMEM;
@@ -270,6 +269,7 @@ static int sr_late_init(struct omap_sr *sr_info)
0, name, (void *)sr_info);
if (ret)
goto error;
+ disable_irq(sr_info->irq);
}
if (pdata && pdata->enable_on_init)
@@ -278,16 +278,16 @@ static int sr_late_init(struct omap_sr *sr_info)
return ret;
error:
- iounmap(sr_info->base);
- mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
- list_del(&sr_info->node);
- dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
- "interrupt handler. Smartreflex will"
- "not function as desired\n", __func__);
- kfree(name);
- kfree(sr_info);
- return ret;
+ iounmap(sr_info->base);
+ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+ list_del(&sr_info->node);
+ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
+ "interrupt handler. Smartreflex will"
+ "not function as desired\n", __func__);
+ kfree(name);
+ kfree(sr_info);
+ return ret;
}
static void sr_v1_disable(struct omap_sr *sr)
@@ -808,10 +808,13 @@ static int omap_sr_autocomp_store(void *data, u64 val)
return -EINVAL;
}
- if (!val)
- sr_stop_vddautocomp(sr_info);
- else
- sr_start_vddautocomp(sr_info);
+ /* control enable/disable only if there is a delta in value */
+ if (sr_info->autocomp_active != val) {
+ if (!val)
+ sr_stop_vddautocomp(sr_info);
+ else
+ sr_start_vddautocomp(sr_info);
+ }
return 0;
}
@@ -824,9 +827,10 @@ static int __init omap_sr_probe(struct platform_device *pdev)
struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
struct omap_sr_data *pdata = pdev->dev.platform_data;
struct resource *mem, *irq;
- struct dentry *vdd_dbg_dir, *nvalue_dir;
+ struct dentry *nvalue_dir;
struct omap_volt_data *volt_data;
int i, ret = 0;
+ char *name;
if (!sr_info) {
dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
@@ -896,18 +900,25 @@ static int __init omap_sr_probe(struct platform_device *pdev)
}
dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
+ if (!sr_dbg_dir) {
+ sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
+ if (!sr_dbg_dir) {
+ ret = PTR_ERR(sr_dbg_dir);
+ pr_err("%s:sr debugfs dir creation failed(%d)\n",
+ __func__, ret);
+ goto err_iounmap;
+ }
+ }
- /*
- * If the voltage domain debugfs directory is not created, do
- * not try to create rest of the debugfs entries.
- */
- vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
- if (!vdd_dbg_dir) {
- ret = -EINVAL;
+ name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
+ if (!name) {
+ dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n",
+ __func__);
+ ret = -ENOMEM;
goto err_iounmap;
}
-
- sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
+ sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir);
+ kfree(name);
if (IS_ERR(sr_info->dbg_dir)) {
dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
__func__);
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 5f35b9e..fd61498 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -152,6 +152,15 @@ struct omap_sr_pmic_data {
void (*sr_pmic_init) (void);
};
+/**
+ * struct omap_smartreflex_dev_attr - Smartreflex Device attribute.
+ *
+ * @sensor_voltdm_name: Name of voltdomain of SR instance
+ */
+struct omap_smartreflex_dev_attr {
+ const char *sensor_voltdm_name;
+};
+
#ifdef CONFIG_OMAP_SMARTREFLEX
/*
* The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index 10d3c5e..0b74f5b 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -82,6 +82,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
struct omap_sr_data *sr_data;
struct omap_device *od;
struct omap_volt_data *volt_data;
+ struct omap_smartreflex_dev_attr *sr_dev_attr;
char *name = "smartreflex";
static int i;
@@ -92,9 +93,11 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
return -ENOMEM;
}
- if (!oh->vdd_name) {
+ sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
+ if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
pr_err("%s: No voltage domain specified for %s."
- "Cannot initialize\n", __func__, oh->name);
+ "Cannot initialize\n", __func__,
+ oh->name);
goto exit;
}
@@ -102,10 +105,10 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
sr_data->senn_mod = 0x1;
sr_data->senp_mod = 0x1;
- sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
if (IS_ERR(sr_data->voltdm)) {
pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
- __func__, oh->vdd_name);
+ __func__, sr_dev_attr->sensor_voltdm_name);
goto exit;
}
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
new file mode 100644
index 0000000..2cf520d
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.c
@@ -0,0 +1,454 @@
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <plat/cpu.h>
+
+#include "voltage.h"
+#include "vc.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+
+/**
+ * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
+ * @sa: bit for slave address
+ * @rav: bit for voltage configuration register
+ * @rac: bit for command configuration register
+ * @racen: enable bit for RAC
+ * @cmd: bit for command value set selection
+ *
+ * Channel configuration bits, common for OMAP3+
+ * OMAP3 register: PRM_VC_CH_CONF
+ * OMAP4 register: PRM_VC_CFG_CHANNEL
+ * OMAP5 register: PRM_VC_SMPS_<voltdm>_CONFIG
+ */
+struct omap_vc_channel_cfg {
+ u8 sa;
+ u8 rav;
+ u8 rac;
+ u8 racen;
+ u8 cmd;
+};
+
+static struct omap_vc_channel_cfg vc_default_channel_cfg = {
+ .sa = BIT(0),
+ .rav = BIT(1),
+ .rac = BIT(2),
+ .racen = BIT(3),
+ .cmd = BIT(4),
+};
+
+/*
+ * On OMAP3+, all VC channels have the above default bitfield
+ * configuration, except the OMAP4 MPU channel. This appears
+ * to be a freak accident as every other VC channel has the
+ * default configuration, thus creating a mutant channel config.
+ */
+static struct omap_vc_channel_cfg vc_mutant_channel_cfg = {
+ .sa = BIT(0),
+ .rav = BIT(2),
+ .rac = BIT(3),
+ .racen = BIT(4),
+ .cmd = BIT(1),
+};
+
+static struct omap_vc_channel_cfg *vc_cfg_bits;
+#define CFG_CHANNEL_MASK 0x1f
+
+/**
+ * omap_vc_config_channel - configure VC channel to PMIC mappings
+ * @voltdm: pointer to voltagdomain defining the desired VC channel
+ *
+ * Configures the VC channel to PMIC mappings for the following
+ * PMIC settings
+ * - i2c slave address (SA)
+ * - voltage configuration address (RAV)
+ * - command configuration address (RAC) and enable bit (RACEN)
+ * - command values for ON, ONLP, RET and OFF (CMD)
+ *
+ * This function currently only allows flexible configuration of the
+ * non-default channel. Starting with OMAP4, there are more than 2
+ * channels, with one defined as the default (on OMAP4, it's MPU.)
+ * Only the non-default channel can be configured.
+ */
+static int omap_vc_config_channel(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+
+ /*
+ * For default channel, the only configurable bit is RACEN.
+ * All others must stay at zero (see function comment above.)
+ */
+ if (vc->flags & OMAP_VC_CHANNEL_DEFAULT)
+ vc->cfg_channel &= vc_cfg_bits->racen;
+
+ voltdm->rmw(CFG_CHANNEL_MASK << vc->cfg_channel_sa_shift,
+ vc->cfg_channel << vc->cfg_channel_sa_shift,
+ vc->common->cfg_channel_reg);
+
+ return 0;
+}
+
+/* Voltage scale and accessory APIs */
+int omap_vc_pre_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 *target_vsel, u8 *current_vsel)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u32 vc_cmdval;
+
+ /* Check if sufficient pmic info is available for this vdd */
+ if (!voltdm->pmic) {
+ pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: PMIC function to convert voltage in uV to"
+ "vsel not registered. Hence unable to scale voltage"
+ "for vdd_%s\n", __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ *target_vsel = voltdm->pmic->uv_to_vsel(target_volt);
+ *current_vsel = voltdm->read(voltdm->vp->voltage);
+
+ /* Setting the ON voltage to the new target voltage */
+ vc_cmdval = voltdm->read(vc->cmdval_reg);
+ vc_cmdval &= ~vc->common->cmd_on_mask;
+ vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
+ voltdm->write(vc_cmdval, vc->cmdval_reg);
+
+ omap_vp_update_errorgain(voltdm, target_volt);
+
+ return 0;
+}
+
+void omap_vc_post_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 target_vsel, u8 current_vsel)
+{
+ u32 smps_steps = 0, smps_delay = 0;
+
+ smps_steps = abs(target_vsel - current_vsel);
+ /* SMPS slew rate / step size. 2us added as buffer. */
+ smps_delay = ((smps_steps * voltdm->pmic->step_size) /
+ voltdm->pmic->slew_rate) + 2;
+ udelay(smps_delay);
+
+ voltdm->curr_volt = target_volt;
+}
+
+static int omap_vc_bypass_send_value(struct voltagedomain *voltdm,
+ struct omap_vc_channel *vc, u8 sa, u8 reg, u32 data)
+{
+ u32 loop_cnt = 0, retries_cnt = 0;
+ u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
+
+ if (IS_ERR_OR_NULL(vc->common)) {
+ pr_err("%s voldm=%s bad value for vc->common\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ vc_valid = vc->common->valid;
+ vc_bypass_val_reg = vc->common->bypass_val_reg;
+ vc_bypass_value = (data << vc->common->data_shift) |
+ (reg << vc->common->regaddr_shift) |
+ (sa << vc->common->slaveaddr_shift);
+
+ voltdm->write(vc_bypass_value, vc_bypass_val_reg);
+ voltdm->write(vc_bypass_value | vc_valid, vc_bypass_val_reg);
+
+ vc_bypass_value = voltdm->read(vc_bypass_val_reg);
+ /*
+ * Loop till the bypass command is acknowledged from the SMPS.
+ * NOTE: This is legacy code. The loop count and retry count needs
+ * to be revisited.
+ */
+ while (!(vc_bypass_value & vc_valid)) {
+ loop_cnt++;
+
+ if (retries_cnt > 10) {
+ pr_warning("%s: Retry count exceeded\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (loop_cnt > 50) {
+ retries_cnt++;
+ loop_cnt = 0;
+ udelay(10);
+ }
+ vc_bypass_value = voltdm->read(vc_bypass_val_reg);
+ }
+
+ return 0;
+
+}
+
+/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
+int omap_vc_bypass_scale_voltage(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vc_channel *vc;
+ u8 target_vsel, current_vsel;
+ int ret;
+
+ if (IS_ERR_OR_NULL(voltdm)) {
+ pr_err("%s bad voldm\n", __func__);
+ return -EINVAL;
+ }
+
+ vc = voltdm->vc;
+ if (IS_ERR_OR_NULL(vc)) {
+ pr_err("%s voldm=%s bad vc\n", __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel,
+ &current_vsel);
+ if (ret)
+ return ret;
+
+ ret = omap_vc_bypass_send_value(voltdm, vc, vc->i2c_slave_addr,
+ vc->volt_reg_addr, target_vsel);
+ if (ret)
+ return ret;
+
+ omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+ return 0;
+}
+
+/**
+ * omap_vc_bypass_send_i2c_msg() - Function to control PMIC registers over SRI2C
+ * @voltdm: voltage domain
+ * @slave_addr: slave address of the device.
+ * @reg_addr: register address to access
+ * @data: what do we want to write there
+ *
+ * Many simpler PMICs with a single I2C interface still have configuration
+ * registers that may need population. Typical being slew rate configurations
+ * thermal shutdown configuration etc. When these PMICs are hooked on I2C_SR,
+ * this function allows these configuration registers to be accessed.
+ *
+ * WARNING: Though this could be used for voltage register configurations over
+ * I2C_SR, DONOT use it for that purpose, all the Voltage controller's internal
+ * information is bypassed using this function and must be used judiciously.
+ */
+int omap_vc_bypass_send_i2c_msg(struct voltagedomain *voltdm, u8 slave_addr,
+ u8 reg_addr, u8 data)
+{
+ struct omap_vc_channel *vc;
+
+ if (IS_ERR_OR_NULL(voltdm)) {
+ pr_err("%s bad voldm\n", __func__);
+ return -EINVAL;
+ }
+
+ vc = voltdm->vc;
+ if (IS_ERR_OR_NULL(vc)) {
+ pr_err("%s voldm=%s bad vc\n", __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ return omap_vc_bypass_send_value(voltdm, vc, slave_addr,
+ reg_addr, data);
+}
+
+static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
+{
+ /*
+ * Voltage Manager FSM parameters init
+ * XXX This data should be passed in from the board file
+ */
+ voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
+ voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
+ voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+}
+
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+ static bool is_initialized;
+
+ if (is_initialized)
+ return;
+
+ omap3_vfsm_init(voltdm);
+
+ is_initialized = true;
+}
+
+
+/* OMAP4 specific voltage init functions */
+static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
+{
+ static bool is_initialized;
+ struct omap_voltdm_pmic *pmic = voltdm->pmic;
+ u32 vc_val = 0;
+
+ if (is_initialized)
+ return;
+
+ if (pmic->i2c_high_speed) {
+ vc_val |= pmic->i2c_hscll_low << OMAP4430_HSCLL_SHIFT;
+ vc_val |= pmic->i2c_hscll_high << OMAP4430_HSCLH_SHIFT;
+ }
+
+ vc_val |= pmic->i2c_scll_low << OMAP4430_SCLL_SHIFT;
+ vc_val |= pmic->i2c_scll_high << OMAP4430_SCLH_SHIFT;
+
+ if (vc_val)
+ voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+
+ is_initialized = true;
+}
+
+/**
+ * omap_vc_i2c_init - initialize I2C interface to PMIC
+ * @voltdm: voltage domain containing VC data
+ *
+ * Use PMIC supplied seetings for I2C high-speed mode and
+ * master code (if set) and program the VC I2C configuration
+ * register.
+ *
+ * The VC I2C configuration is common to all VC channels,
+ * so this function only configures I2C for the first VC
+ * channel registers. All other VC channels will use the
+ * same configuration.
+ */
+static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ static bool initialized;
+ static bool i2c_high_speed;
+ u8 mcode;
+
+ if (initialized) {
+ if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
+ pr_warn("%s: I2C config for all channels must match.",
+ __func__);
+ return;
+ }
+
+ i2c_high_speed = voltdm->pmic->i2c_high_speed;
+ if (i2c_high_speed)
+ voltdm->rmw(vc->common->i2c_cfg_hsen_mask,
+ vc->common->i2c_cfg_hsen_mask,
+ vc->common->i2c_cfg_reg);
+
+ mcode = voltdm->pmic->i2c_mcode;
+ if (mcode)
+ voltdm->rmw(vc->common->i2c_mcode_mask,
+ mcode << __ffs(vc->common->i2c_mcode_mask),
+ vc->common->i2c_cfg_reg);
+
+ initialized = true;
+}
+
+void __init omap_vc_init_channel(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ u32 val;
+
+ if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: PMIC info requried to configure vc for"
+ "vdd_%s not populated.Hence cannot initialize vc\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vc->cfg_channel = 0;
+ if (vc->flags & OMAP_VC_CHANNEL_CFG_MUTANT)
+ vc_cfg_bits = &vc_mutant_channel_cfg;
+ else
+ vc_cfg_bits = &vc_default_channel_cfg;
+
+ /* get PMIC/board specific settings */
+ vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
+ vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
+ vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
+ vc->setup_time = voltdm->pmic->volt_setup_time;
+
+ if ((vc->flags & OMAP_VC_CHANNEL_DEFAULT) &&
+ ((vc->i2c_slave_addr == USE_DEFAULT_CHANNEL_I2C_PARAM) ||
+ (vc->cmd_reg_addr == USE_DEFAULT_CHANNEL_I2C_PARAM) ||
+ (vc->volt_reg_addr == USE_DEFAULT_CHANNEL_I2C_PARAM))) {
+ pr_err("%s: voltdm %s: default channel "
+ "bad config-sa=%2x vol=%2x, cmd=%2x?\n", __func__,
+ voltdm->name, vc->i2c_slave_addr, vc->volt_reg_addr,
+ vc->cmd_reg_addr);
+ return;
+ }
+
+ /* Configure the i2c slave address for this VC */
+ if (vc->i2c_slave_addr != USE_DEFAULT_CHANNEL_I2C_PARAM) {
+ voltdm->rmw(vc->smps_sa_mask,
+ vc->i2c_slave_addr << __ffs(vc->smps_sa_mask),
+ vc->common->smps_sa_reg);
+ vc->cfg_channel |= vc_cfg_bits->sa;
+ }
+
+ /*
+ * Configure the PMIC register addresses.
+ */
+ if (vc->volt_reg_addr != USE_DEFAULT_CHANNEL_I2C_PARAM) {
+ voltdm->rmw(vc->smps_volra_mask,
+ vc->volt_reg_addr << __ffs(vc->smps_volra_mask),
+ vc->common->smps_volra_reg);
+ vc->cfg_channel |= vc_cfg_bits->rav;
+ }
+
+ if (vc->cmd_reg_addr != USE_DEFAULT_CHANNEL_I2C_PARAM) {
+ voltdm->rmw(vc->smps_cmdra_mask,
+ vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
+ vc->common->smps_cmdra_reg);
+ vc->cfg_channel |= vc_cfg_bits->rac;
+ }
+
+ /* If voltage and cmd regs are same, we can use cmdra register */
+ if (vc->volt_reg_addr == vc->cmd_reg_addr)
+ vc->cfg_channel |= vc_cfg_bits->racen;
+
+ /* Set up the on, inactive, retention and off voltage */
+ on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
+ onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
+ ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
+ off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
+ val = ((on_vsel << vc->common->cmd_on_shift) |
+ (onlp_vsel << vc->common->cmd_onlp_shift) |
+ (ret_vsel << vc->common->cmd_ret_shift) |
+ (off_vsel << vc->common->cmd_off_shift));
+ voltdm->write(val, vc->cmdval_reg);
+ vc->cfg_channel |= vc_cfg_bits->cmd;
+
+ /* Channel configuration */
+ omap_vc_config_channel(voltdm);
+
+ /* Configure the setup times */
+ voltdm->rmw(voltdm->vfsm->voltsetup_mask,
+ vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
+ voltdm->vfsm->voltsetup_reg);
+
+ omap_vc_i2c_init(voltdm);
+
+ if (cpu_is_omap34xx())
+ omap3_vc_init_channel(voltdm);
+ else if (cpu_is_omap44xx())
+ omap4_vc_init_channel(voltdm);
+}
+
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index e776777..cf20f47 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -19,8 +19,10 @@
#include <linux/kernel.h>
+struct voltagedomain;
+
/**
- * struct omap_vc_common_data - per-VC register/bitfield data
+ * struct omap_vc_common - per-VC register/bitfield data
* @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register
* @valid: VALID bitmask in PRM_VC_BYPASS_VAL register
* @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
@@ -33,15 +35,19 @@
* @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register
* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
* @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
+ * @i2c_cfg_reg: I2C configuration register offset
+ * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register
+ * @i2c_mcode_mask: MCODE field mask for I2C config register
*
* XXX One of cmd_on_mask and cmd_on_shift are not needed
* XXX VALID should probably be a shift, not a mask
*/
-struct omap_vc_common_data {
+struct omap_vc_common {
u32 cmd_on_mask;
u32 valid;
u8 smps_sa_reg;
u8 smps_volra_reg;
+ u8 smps_cmdra_reg;
u8 bypass_val_reg;
u8 data_shift;
u8 slaveaddr_shift;
@@ -50,34 +56,60 @@ struct omap_vc_common_data {
u8 cmd_onlp_shift;
u8 cmd_ret_shift;
u8 cmd_off_shift;
+ u8 cfg_channel_reg;
+ u8 i2c_cfg_reg;
+ u8 i2c_cfg_hsen_mask;
+ u8 i2c_mcode_mask;
};
+/* omap_vc_channel.flags values */
+#define OMAP_VC_CHANNEL_DEFAULT BIT(0)
+#define OMAP_VC_CHANNEL_CFG_MUTANT BIT(1)
+
/**
- * struct omap_vc_instance_data - VC per-instance data
- * @vc_common: pointer to VC common data for this platform
- * @smps_sa_mask: SA* bitmask in the PRM_VC_SMPS_SA register
+ * struct omap_vc_channel - VC per-instance data
+ * @flags: VC channel-specific flags (optional)
+ * @common: pointer to VC common data for this platform
+ * @smps_sa_mask: i2c slave address bitmask in the PRM_VC_SMPS_SA register
* @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
- * @smps_sa_shift: SA* field shift in the PRM_VC_SMPS_SA register
- * @smps_volra_shift: VOLRA* field shift in the PRM_VC_VOL_RA register
- *
- * XXX It is not necessary to have both a *_mask and a *_shift -
- * remove one
*/
-struct omap_vc_instance_data {
- const struct omap_vc_common_data *vc_common;
+struct omap_vc_channel {
+ u8 flags;
+
+ /* channel state */
+ u16 i2c_slave_addr;
+ u16 volt_reg_addr;
+ u16 cmd_reg_addr;
+ u8 cfg_channel;
+ u16 setup_time;
+ bool i2c_high_speed;
+
+ /* register access data */
+ const struct omap_vc_common *common;
u32 smps_sa_mask;
u32 smps_volra_mask;
+ u32 smps_cmdra_mask;
u8 cmdval_reg;
- u8 smps_sa_shift;
- u8 smps_volra_shift;
+ u8 cfg_channel_sa_shift;
};
-extern struct omap_vc_instance_data omap3_vc1_data;
-extern struct omap_vc_instance_data omap3_vc2_data;
+extern struct omap_vc_channel omap3_vc_mpu;
+extern struct omap_vc_channel omap3_vc_core;
-extern struct omap_vc_instance_data omap4_vc_mpu_data;
-extern struct omap_vc_instance_data omap4_vc_iva_data;
-extern struct omap_vc_instance_data omap4_vc_core_data;
+extern struct omap_vc_channel omap4_vc_mpu;
+extern struct omap_vc_channel omap4_vc_iva;
+extern struct omap_vc_channel omap4_vc_core;
+void omap_vc_init_channel(struct voltagedomain *voltdm);
+int omap_vc_pre_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 *target_vsel, u8 *current_vsel);
+void omap_vc_post_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 target_vsel, u8 current_vsel);
+int omap_vc_bypass_scale_voltage(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+int omap_vc_bypass_send_i2c_msg(struct voltagedomain *voltdm,
+ u8 slave_addr, u8 reg_addr, u8 data);
#endif
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index f37dc4b..95d7701 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -29,9 +29,10 @@
* VC data common to 34xx/36xx chips
* XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
*/
-static struct omap_vc_common_data omap3_vc_common = {
+static struct omap_vc_common omap3_vc_common = {
.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET,
.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET,
.data_shift = OMAP3430_DATA_SHIFT,
.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT,
@@ -42,22 +43,26 @@ static struct omap_vc_common_data omap3_vc_common = {
.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT,
.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT,
.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT,
+ .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET,
+ .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK,
+ .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET,
+ .i2c_mcode_mask = OMAP3430_MCODE_MASK,
};
-struct omap_vc_instance_data omap3_vc1_data = {
- .vc_common = &omap3_vc_common,
+struct omap_vc_channel omap3_vc_mpu = {
+ .common = &omap3_vc_common,
.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
- .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
- .smps_volra_shift = OMAP3430_VOLRA0_SHIFT,
.smps_volra_mask = OMAP3430_VOLRA0_MASK,
+ .smps_cmdra_mask = OMAP3430_CMDRA0_MASK,
+ .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
};
-struct omap_vc_instance_data omap3_vc2_data = {
- .vc_common = &omap3_vc_common,
+struct omap_vc_channel omap3_vc_core = {
+ .common = &omap3_vc_common,
.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
- .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
- .smps_volra_shift = OMAP3430_VOLRA1_SHIFT,
.smps_volra_mask = OMAP3430_VOLRA1_MASK,
+ .smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
+ .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index a98da8d..0a4fc37 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -30,9 +30,10 @@
* VC data common to 44xx chips
* XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
*/
-static const struct omap_vc_common_data omap4_vc_common = {
+static const struct omap_vc_common omap4_vc_common = {
.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
.data_shift = OMAP4430_DATA_SHIFT,
.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
@@ -43,33 +44,38 @@ static const struct omap_vc_common_data omap4_vc_common = {
.cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
.cmd_ret_shift = OMAP4430_RET_SHIFT,
.cmd_off_shift = OMAP4430_OFF_SHIFT,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
+ .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET,
+ .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK,
+ .i2c_mcode_mask = OMAP4430_HSMCODE_MASK,
};
/* VC instance data for each controllable voltage line */
-struct omap_vc_instance_data omap4_vc_mpu_data = {
- .vc_common = &omap4_vc_common,
+struct omap_vc_channel omap4_vc_mpu = {
+ .flags = OMAP_VC_CHANNEL_DEFAULT | OMAP_VC_CHANNEL_CFG_MUTANT,
+ .common = &omap4_vc_common,
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
- .smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
.smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
- .smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT,
.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
};
-struct omap_vc_instance_data omap4_vc_iva_data = {
- .vc_common = &omap4_vc_common,
+struct omap_vc_channel omap4_vc_iva = {
+ .common = &omap4_vc_common,
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
- .smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
.smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
- .smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT,
.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
};
-struct omap_vc_instance_data omap4_vc_core_data = {
- .vc_common = &omap4_vc_common,
+struct omap_vc_channel omap4_vc_core = {
+ .common = &omap4_vc_common,
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
- .smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
- .smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT,
.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
};
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 9ef3789..a501597 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -36,633 +36,51 @@
#include "control.h"
#include "voltage.h"
+#include "powerdomain.h"
#include "vc.h"
#include "vp.h"
-#define VOLTAGE_DIR_SIZE 16
+static LIST_HEAD(voltdm_list);
-
-static struct omap_vdd_info **vdd_info;
-
-/*
- * Number of scalable voltage domains.
- */
-static int nr_scalable_vdd;
-
-/* XXX document */
-static s16 prm_mod_offs;
-static s16 prm_irqst_ocp_mod_offs;
-
-static struct dentry *voltage_dir;
-
-/* Init function pointers */
-static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
- unsigned long target_volt);
-
-static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
-{
- return omap2_prm_read_mod_reg(mod, offset);
-}
-
-static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset)
+static int __init _config_common_vdd_data(struct voltagedomain *voltdm)
{
- omap2_prm_write_mod_reg(val, mod, offset);
-}
-
-static u32 omap4_voltage_read_reg(u16 mod, u8 offset)
-{
- return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
- mod, offset);
-}
-
-static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
-{
- omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
-}
-
-static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
-{
- char *sys_ck_name;
struct clk *sys_ck;
- u32 sys_clk_speed, timeout_val, waittime;
-
- /*
- * XXX Clockfw should handle this, or this should be in a
- * struct record
- */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- sys_ck_name = "sys_ck";
- else if (cpu_is_omap44xx())
- sys_ck_name = "sys_clkin_ck";
- else
- return -EINVAL;
/*
* Sys clk rate is require to calculate vp timeout value and
* smpswaittimemin and smpswaittimemax.
*/
- sys_ck = clk_get(NULL, sys_ck_name);
+ sys_ck = clk_get(NULL, voltdm->sys_clk.name);
if (IS_ERR(sys_ck)) {
pr_warning("%s: Could not get the sys clk to calculate"
- "various vdd_%s params\n", __func__, vdd->voltdm.name);
+ "various vdd_%s params\n", __func__, voltdm->name);
return -EINVAL;
}
- sys_clk_speed = clk_get_rate(sys_ck);
- clk_put(sys_ck);
- /* Divide to avoid overflow */
- sys_clk_speed /= 1000;
+ voltdm->sys_clk.rate = clk_get_rate(sys_ck);
+ WARN_ON(!voltdm->sys_clk.rate);
/* Generic voltage parameters */
- vdd->volt_scale = vp_forceupdate_scale_voltage;
- vdd->vp_enabled = false;
-
- vdd->vp_rt_data.vpconfig_erroroffset =
- (vdd->pmic_info->vp_erroroffset <<
- vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
-
- timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
- vdd->vp_rt_data.vlimitto_timeout = timeout_val;
- vdd->vp_rt_data.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
- vdd->vp_rt_data.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
-
- waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
- sys_clk_speed) / 1000;
- vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
- vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
- vdd->vp_rt_data.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
- vdd->vp_rt_data.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
-
- return 0;
-}
-
-/* Voltage debugfs support */
-static int vp_volt_debug_get(void *data, u64 *val)
-{
- struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
- u8 vsel;
-
- if (!vdd) {
- pr_warning("Wrong paramater passed\n");
- return -EINVAL;
- }
-
- vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-
- if (!vdd->pmic_info->vsel_to_uv) {
- pr_warning("PMIC function to convert vsel to voltage"
- "in uV not registerd\n");
- return -EINVAL;
- }
-
- *val = vdd->pmic_info->vsel_to_uv(vsel);
- return 0;
-}
-
-static int nom_volt_debug_get(void *data, u64 *val)
-{
- struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
-
- if (!vdd) {
- pr_warning("Wrong paramater passed\n");
- return -EINVAL;
- }
-
- *val = omap_voltage_get_nom_volt(&vdd->voltdm);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
-DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
- "%llu\n");
-static void vp_latch_vsel(struct omap_vdd_info *vdd)
-{
- u32 vpconfig;
- unsigned long uvdc;
- char vsel;
-
- uvdc = omap_voltage_get_nom_volt(&vdd->voltdm);
- if (!uvdc) {
- pr_warning("%s: unable to find current voltage for vdd_%s\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
- pr_warning("%s: PMIC function to convert voltage in uV to"
- " vsel not registered\n", __func__);
- return;
- }
-
- vsel = vdd->pmic_info->uv_to_vsel(uvdc);
-
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvoltage_mask |
- vdd->vp_data->vp_common->vpconfig_initvdd);
- vpconfig |= vsel << vdd->vp_data->vp_common->vpconfig_initvoltage_shift;
-
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Trigger initVDD value copy to voltage processor */
- vdd->write_reg((vpconfig | vdd->vp_data->vp_common->vpconfig_initvdd),
- prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Clear initVDD copy trigger bit */
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-}
-
-/* Generic voltage init functions */
-static void __init vp_init(struct omap_vdd_info *vdd)
-{
- u32 vp_val;
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
- (vdd->vp_rt_data.vpconfig_errorgain <<
- vdd->vp_data->vp_common->vpconfig_errorgain_shift) |
- vdd->vp_data->vp_common->vpconfig_timeouten;
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vpconfig);
-
- vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
- vdd->vp_data->vp_common->vstepmin_smpswaittimemin_shift) |
- (vdd->vp_rt_data.vstepmin_stepmin <<
- vdd->vp_data->vp_common->vstepmin_stepmin_shift));
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmin);
-
- vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
- vdd->vp_data->vp_common->vstepmax_smpswaittimemax_shift) |
- (vdd->vp_rt_data.vstepmax_stepmax <<
- vdd->vp_data->vp_common->vstepmax_stepmax_shift));
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmax);
-
- vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
- vdd->vp_data->vp_common->vlimitto_vddmax_shift) |
- (vdd->vp_rt_data.vlimitto_vddmin <<
- vdd->vp_data->vp_common->vlimitto_vddmin_shift) |
- (vdd->vp_rt_data.vlimitto_timeout <<
- vdd->vp_data->vp_common->vlimitto_timeout_shift));
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vlimitto);
-}
-
-static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
-{
- char *name;
-
- name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);
- if (!name) {
- pr_warning("%s: Unable to allocate memory for debugfs"
- " directory name for vdd_%s",
- __func__, vdd->voltdm.name);
- return;
- }
- strcpy(name, "vdd_");
- strcat(name, vdd->voltdm.name);
-
- vdd->debug_dir = debugfs_create_dir(name, voltage_dir);
- kfree(name);
- if (IS_ERR(vdd->debug_dir)) {
- pr_warning("%s: Unable to create debugfs directory for"
- " vdd_%s\n", __func__, vdd->voltdm.name);
- vdd->debug_dir = NULL;
- return;
- }
-
- (void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vpconfig_errorgain));
- (void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
- vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmin_smpswaittimemin));
- (void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmin_stepmin));
- (void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
- vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmax_smpswaittimemax));
- (void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmax_stepmax));
- (void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vlimitto_vddmax));
- (void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vlimitto_vddmin));
- (void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vlimitto_timeout));
- (void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
- (void *) vdd, &vp_volt_debug_fops);
- (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
- vdd->debug_dir, (void *) vdd,
- &nom_volt_debug_fops);
-}
-
-/* Voltage scale and accessory APIs */
-static int _pre_volt_scale(struct omap_vdd_info *vdd,
- unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
-{
- struct omap_volt_data *volt_data;
- const struct omap_vc_common_data *vc_common;
- const struct omap_vp_common_data *vp_common;
- u32 vc_cmdval, vp_errgain_val;
-
- vc_common = vdd->vc_data->vc_common;
- vp_common = vdd->vp_data->vp_common;
-
- /* Check if suffiecient pmic info is available for this vdd */
- if (!vdd->pmic_info) {
- pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
- __func__, vdd->voltdm.name);
- return -EINVAL;
- }
+ voltdm->scale = omap_vp_forceupdate_scale;
- if (!vdd->pmic_info->uv_to_vsel) {
- pr_err("%s: PMIC function to convert voltage in uV to"
- "vsel not registered. Hence unable to scale voltage"
- "for vdd_%s\n", __func__, vdd->voltdm.name);
- return -ENODATA;
- }
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
- return -EINVAL;
- }
-
- /* Get volt_data corresponding to target_volt */
- volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
- if (IS_ERR(volt_data))
- volt_data = NULL;
-
- *target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
- *current_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-
- /* Setting the ON voltage to the new target voltage */
- vc_cmdval = vdd->read_reg(prm_mod_offs, vdd->vc_data->cmdval_reg);
- vc_cmdval &= ~vc_common->cmd_on_mask;
- vc_cmdval |= (*target_vsel << vc_common->cmd_on_shift);
- vdd->write_reg(vc_cmdval, prm_mod_offs, vdd->vc_data->cmdval_reg);
-
- /* Setting vp errorgain based on the voltage */
- if (volt_data) {
- vp_errgain_val = vdd->read_reg(prm_mod_offs,
- vdd->vp_data->vpconfig);
- vdd->vp_rt_data.vpconfig_errorgain = volt_data->vp_errgain;
- vp_errgain_val &= ~vp_common->vpconfig_errorgain_mask;
- vp_errgain_val |= vdd->vp_rt_data.vpconfig_errorgain <<
- vp_common->vpconfig_errorgain_shift;
- vdd->write_reg(vp_errgain_val, prm_mod_offs,
- vdd->vp_data->vpconfig);
- }
-
- return 0;
-}
-
-static void _post_volt_scale(struct omap_vdd_info *vdd,
- unsigned long target_volt, u8 target_vsel, u8 current_vsel)
-{
- u32 smps_steps = 0, smps_delay = 0;
-
- smps_steps = abs(target_vsel - current_vsel);
- /* SMPS slew rate / step size. 2us added as buffer. */
- smps_delay = ((smps_steps * vdd->pmic_info->step_size) /
- vdd->pmic_info->slew_rate) + 2;
- udelay(smps_delay);
-
- vdd->curr_volt = target_volt;
-}
-
-/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
-static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
- unsigned long target_volt)
-{
- u32 loop_cnt = 0, retries_cnt = 0;
- u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
- u8 target_vsel, current_vsel;
- int ret;
-
- ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
- if (ret)
- return ret;
-
- vc_valid = vdd->vc_data->vc_common->valid;
- vc_bypass_val_reg = vdd->vc_data->vc_common->bypass_val_reg;
- vc_bypass_value = (target_vsel << vdd->vc_data->vc_common->data_shift) |
- (vdd->pmic_info->pmic_reg <<
- vdd->vc_data->vc_common->regaddr_shift) |
- (vdd->pmic_info->i2c_slave_addr <<
- vdd->vc_data->vc_common->slaveaddr_shift);
-
- vdd->write_reg(vc_bypass_value, prm_mod_offs, vc_bypass_val_reg);
- vdd->write_reg(vc_bypass_value | vc_valid, prm_mod_offs,
- vc_bypass_val_reg);
-
- vc_bypass_value = vdd->read_reg(prm_mod_offs, vc_bypass_val_reg);
- /*
- * Loop till the bypass command is acknowledged from the SMPS.
- * NOTE: This is legacy code. The loop count and retry count needs
- * to be revisited.
- */
- while (!(vc_bypass_value & vc_valid)) {
- loop_cnt++;
-
- if (retries_cnt > 10) {
- pr_warning("%s: Retry count exceeded\n", __func__);
- return -ETIMEDOUT;
- }
-
- if (loop_cnt > 50) {
- retries_cnt++;
- loop_cnt = 0;
- udelay(10);
- }
- vc_bypass_value = vdd->read_reg(prm_mod_offs,
- vc_bypass_val_reg);
- }
-
- _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
return 0;
}
-/* VP force update method of voltage scaling */
-static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
- unsigned long target_volt)
-{
- u32 vpconfig;
- u8 target_vsel, current_vsel, prm_irqst_reg;
- int ret, timeout = 0;
-
- ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
- if (ret)
- return ret;
-
- prm_irqst_reg = vdd->vp_data->prm_irqst_data->prm_irqst_reg;
-
- /*
- * Clear all pending TransactionDone interrupt/status. Typical latency
- * is <3us
- */
- while (timeout++ < VP_TRANXDONE_TIMEOUT) {
- vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
- prm_irqst_ocp_mod_offs, prm_irqst_reg);
- if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
- vdd->vp_data->prm_irqst_data->tranxdone_status))
- break;
- udelay(1);
- }
- if (timeout >= VP_TRANXDONE_TIMEOUT) {
- pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
- "Voltage change aborted", __func__, vdd->voltdm.name);
- return -ETIMEDOUT;
- }
-
- /* Configure for VP-Force Update */
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvdd |
- vdd->vp_data->vp_common->vpconfig_forceupdate |
- vdd->vp_data->vp_common->vpconfig_initvoltage_mask);
- vpconfig |= ((target_vsel <<
- vdd->vp_data->vp_common->vpconfig_initvoltage_shift));
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Trigger initVDD value copy to voltage processor */
- vpconfig |= vdd->vp_data->vp_common->vpconfig_initvdd;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Force update of voltage */
- vpconfig |= vdd->vp_data->vp_common->vpconfig_forceupdate;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /*
- * Wait for TransactionDone. Typical latency is <200us.
- * Depends on SMPSWAITTIMEMIN/MAX and voltage change
- */
- timeout = 0;
- omap_test_timeout((vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
- vdd->vp_data->prm_irqst_data->tranxdone_status),
- VP_TRANXDONE_TIMEOUT, timeout);
- if (timeout >= VP_TRANXDONE_TIMEOUT)
- pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
- "TRANXDONE never got set after the voltage update\n",
- __func__, vdd->voltdm.name);
-
- _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
-
- /*
- * Disable TransactionDone interrupt , clear all status, clear
- * control registers
- */
- timeout = 0;
- while (timeout++ < VP_TRANXDONE_TIMEOUT) {
- vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
- prm_irqst_ocp_mod_offs, prm_irqst_reg);
- if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
- vdd->vp_data->prm_irqst_data->tranxdone_status))
- break;
- udelay(1);
- }
-
- if (timeout >= VP_TRANXDONE_TIMEOUT)
- pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
- "to clear the TRANXDONE status\n",
- __func__, vdd->voltdm.name);
-
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- /* Clear initVDD copy trigger bit */
- vpconfig &= ~vdd->vp_data->vp_common->vpconfig_initvdd;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
- /* Clear force bit */
- vpconfig &= ~vdd->vp_data->vp_common->vpconfig_forceupdate;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- return 0;
-}
-
-static void __init omap3_vfsm_init(struct omap_vdd_info *vdd)
-{
- /*
- * Voltage Manager FSM parameters init
- * XXX This data should be passed in from the board file
- */
- vdd->write_reg(OMAP3_CLKSETUP, prm_mod_offs, OMAP3_PRM_CLKSETUP_OFFSET);
- vdd->write_reg(OMAP3_VOLTOFFSET, prm_mod_offs,
- OMAP3_PRM_VOLTOFFSET_OFFSET);
- vdd->write_reg(OMAP3_VOLTSETUP2, prm_mod_offs,
- OMAP3_PRM_VOLTSETUP2_OFFSET);
-}
-
-static void __init omap3_vc_init(struct omap_vdd_info *vdd)
-{
- static bool is_initialized;
- u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
- u32 vc_val;
-
- if (is_initialized)
- return;
-
- /* Set up the on, inactive, retention and off voltage */
- on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
- onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
- ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
- off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
- vc_val = ((on_vsel << vdd->vc_data->vc_common->cmd_on_shift) |
- (onlp_vsel << vdd->vc_data->vc_common->cmd_onlp_shift) |
- (ret_vsel << vdd->vc_data->vc_common->cmd_ret_shift) |
- (off_vsel << vdd->vc_data->vc_common->cmd_off_shift));
- vdd->write_reg(vc_val, prm_mod_offs, vdd->vc_data->cmdval_reg);
-
- /*
- * Generic VC parameters init
- * XXX This data should be abstracted out
- */
- vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, prm_mod_offs,
- OMAP3_PRM_VC_CH_CONF_OFFSET);
- vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, prm_mod_offs,
- OMAP3_PRM_VC_I2C_CFG_OFFSET);
-
- omap3_vfsm_init(vdd);
-
- is_initialized = true;
-}
-
-
-/* OMAP4 specific voltage init functions */
-static void __init omap4_vc_init(struct omap_vdd_info *vdd)
-{
- static bool is_initialized;
- u32 vc_val;
-
- if (is_initialized)
- return;
-
- /* TODO: Configure setup times and CMD_VAL values*/
-
- /*
- * Generic VC parameters init
- * XXX This data should be abstracted out
- */
- vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
- OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
- OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
- vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
-
- /* XXX These are magic numbers and do not belong! */
- vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
- vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
-
- is_initialized = true;
-}
-
-static void __init omap_vc_init(struct omap_vdd_info *vdd)
-{
- u32 vc_val;
-
- if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
- pr_err("%s: PMIC info requried to configure vc for"
- "vdd_%s not populated.Hence cannot initialize vc\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- /* Set up the SMPS_SA(i2c slave address in VC */
- vc_val = vdd->read_reg(prm_mod_offs,
- vdd->vc_data->vc_common->smps_sa_reg);
- vc_val &= ~vdd->vc_data->smps_sa_mask;
- vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_data->smps_sa_shift;
- vdd->write_reg(vc_val, prm_mod_offs,
- vdd->vc_data->vc_common->smps_sa_reg);
-
- /* Setup the VOLRA(pmic reg addr) in VC */
- vc_val = vdd->read_reg(prm_mod_offs,
- vdd->vc_data->vc_common->smps_volra_reg);
- vc_val &= ~vdd->vc_data->smps_volra_mask;
- vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_data->smps_volra_shift;
- vdd->write_reg(vc_val, prm_mod_offs,
- vdd->vc_data->vc_common->smps_volra_reg);
-
- /* Configure the setup times */
- vc_val = vdd->read_reg(prm_mod_offs, vdd->vfsm->voltsetup_reg);
- vc_val &= ~vdd->vfsm->voltsetup_mask;
- vc_val |= vdd->pmic_info->volt_setup_time <<
- vdd->vfsm->voltsetup_shift;
- vdd->write_reg(vc_val, prm_mod_offs, vdd->vfsm->voltsetup_reg);
-
- if (cpu_is_omap34xx())
- omap3_vc_init(vdd);
- else if (cpu_is_omap44xx())
- omap4_vc_init(vdd);
-}
-
-static int __init omap_vdd_data_configure(struct omap_vdd_info *vdd)
+static int __init omap_vdd_data_configure(struct voltagedomain *voltdm)
{
int ret = -EINVAL;
- if (!vdd->pmic_info) {
+ if (!voltdm->pmic) {
pr_err("%s: PMIC info requried to configure vdd_%s not"
"populated.Hence cannot initialize vdd_%s\n",
- __func__, vdd->voltdm.name, vdd->voltdm.name);
+ __func__, voltdm->name, voltdm->name);
goto ovdc_out;
}
- if (IS_ERR_VALUE(_config_common_vdd_data(vdd)))
+ if (IS_ERR_VALUE(_config_common_vdd_data(voltdm)))
goto ovdc_out;
- if (cpu_is_omap34xx()) {
- vdd->read_reg = omap3_voltage_read_reg;
- vdd->write_reg = omap3_voltage_write_reg;
- ret = 0;
- } else if (cpu_is_omap44xx()) {
- vdd->read_reg = omap4_voltage_read_reg;
- vdd->write_reg = omap4_voltage_write_reg;
- ret = 0;
- }
+ ret = 0;
ovdc_out:
return ret;
@@ -678,197 +96,65 @@ ovdc_out:
*/
unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
{
- struct omap_vdd_info *vdd;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return 0;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- return vdd->curr_volt;
-}
-
-/**
- * omap_vp_get_curr_volt() - API to get the current vp voltage.
- * @voltdm: pointer to the VDD.
- *
- * This API returns the current voltage for the specified voltage processor
- */
-unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
- u8 curr_vsel;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return 0;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
- if (!vdd->read_reg) {
- pr_err("%s: No read API for reading vdd_%s regs\n",
- __func__, voltdm->name);
- return 0;
- }
-
- curr_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-
- if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
- pr_warning("%s: PMIC function to convert vsel to voltage"
- "in uV not registerd\n", __func__);
- return 0;
- }
-
- return vdd->pmic_info->vsel_to_uv(curr_vsel);
-}
-
-/**
- * omap_vp_enable() - API to enable a particular VP
- * @voltdm: pointer to the VDD whose VP is to be enabled.
- *
- * This API enables a particular voltage processor. Needed by the smartreflex
- * class drivers.
- */
-void omap_vp_enable(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
- u32 vpconfig;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, voltdm->name);
- return;
- }
-
- /* If VP is already enabled, do nothing. Return */
- if (vdd->vp_enabled)
- return;
-
- vp_latch_vsel(vdd);
-
- /* Enable VP */
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig |= vdd->vp_data->vp_common->vpconfig_vpenable;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
- vdd->vp_enabled = true;
+ return voltdm->curr_volt;
}
/**
- * omap_vp_disable() - API to disable a particular VP
- * @voltdm: pointer to the VDD whose VP is to be disabled.
- *
- * This API disables a particular voltage processor. Needed by the smartreflex
- * class drivers.
- */
-void omap_vp_disable(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
- u32 vpconfig;
- int timeout;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, voltdm->name);
- return;
- }
-
- /* If VP is already disabled, do nothing. Return */
- if (!vdd->vp_enabled) {
- pr_warning("%s: Trying to disable VP for vdd_%s when"
- "it is already disabled\n", __func__, voltdm->name);
- return;
- }
-
- /* Disable VP */
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig &= ~vdd->vp_data->vp_common->vpconfig_vpenable;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /*
- * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
- */
- omap_test_timeout((vdd->read_reg(prm_mod_offs, vdd->vp_data->vstatus)),
- VP_IDLE_TIMEOUT, timeout);
-
- if (timeout >= VP_IDLE_TIMEOUT)
- pr_warning("%s: vdd_%s idle timedout\n",
- __func__, voltdm->name);
-
- vdd->vp_enabled = false;
-
- return;
-}
-
-/**
- * omap_voltage_scale_vdd() - API to scale voltage of a particular
- * voltage domain.
- * @voltdm: pointer to the VDD which is to be scaled.
- * @target_volt: The target voltage of the voltage domain
+ * voltdm_scale() - API to scale voltage of a particular voltage domain.
+ * @voltdm: pointer to the voltage domain which is to be scaled.
+ * @target_volt: The target voltage of the voltage domain
*
* This API should be called by the kernel to do the voltage scaling
- * for a particular voltage domain during dvfs or any other situation.
+ * for a particular voltage domain during DVFS.
*/
-int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
- unsigned long target_volt)
+int voltdm_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return -EINVAL;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- if (!vdd->volt_scale) {
+ if (!voltdm->scale) {
pr_err("%s: No voltage scale API registered for vdd_%s\n",
__func__, voltdm->name);
return -ENODATA;
}
- return vdd->volt_scale(vdd, target_volt);
+ return voltdm->scale(voltdm, target_volt);
}
/**
- * omap_voltage_reset() - Resets the voltage of a particular voltage domain
- * to that of the current OPP.
- * @voltdm: pointer to the VDD whose voltage is to be reset.
+ * voltdm_reset() - Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @voltdm: pointer to the voltage domain whose voltage is to be reset.
*
* This API finds out the correct voltage the voltage domain is supposed
* to be at and resets the voltage to that level. Should be used especially
* while disabling any voltage compensation modules.
*/
-void omap_voltage_reset(struct voltagedomain *voltdm)
+void voltdm_reset(struct voltagedomain *voltdm)
{
- unsigned long target_uvdc;
+ unsigned long target_volt;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return;
}
- target_uvdc = omap_voltage_get_nom_volt(voltdm);
- if (!target_uvdc) {
+ target_volt = omap_voltage_get_nom_volt(voltdm);
+ if (!target_volt) {
pr_err("%s: unable to find current voltage for vdd_%s\n",
__func__, voltdm->name);
return;
}
- omap_voltage_scale_vdd(voltdm, target_uvdc);
+ voltdm_scale(voltdm, target_volt);
}
/**
@@ -893,7 +179,7 @@ void omap_voltage_get_volttable(struct voltagedomain *voltdm,
return;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ vdd = voltdm->vdd;
*volt_data = vdd->volt_data;
}
@@ -924,7 +210,7 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
return ERR_PTR(-EINVAL);
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ vdd = voltdm->vdd;
if (!vdd->volt_data) {
pr_warning("%s: voltage table does not exist for vdd_%s\n",
@@ -947,54 +233,25 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
* omap_voltage_register_pmic() - API to register PMIC specific data
* @voltdm: pointer to the VDD for which the PMIC specific data is
* to be registered
- * @pmic_info: the structure containing pmic info
+ * @pmic: the structure containing pmic info
*
* This API is to be called by the SOC/PMIC file to specify the
- * pmic specific info as present in omap_volt_pmic_info structure.
+ * pmic specific info as present in omap_voltdm_pmic structure.
*/
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
- struct omap_volt_pmic_info *pmic_info)
+ struct omap_voltdm_pmic *pmic)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return -EINVAL;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- vdd->pmic_info = pmic_info;
+ voltdm->pmic = pmic;
return 0;
}
/**
- * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
- * corresponding to a voltage domain.
- *
- * @voltdm: pointer to the VDD whose debug directory is required.
- *
- * This API returns pointer to the debugfs directory corresponding
- * to the voltage domain. Should be used by drivers requiring to
- * add any debug entry for a particular voltage domain. Returns NULL
- * in case of error.
- */
-struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return NULL;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- return vdd->debug_dir;
-}
-
-/**
* omap_change_voltscale_method() - API to change the voltage scaling method.
* @voltdm: pointer to the VDD whose voltage scaling method
* has to be changed.
@@ -1005,23 +262,19 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
* defined in voltage.h
*/
void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method)
+ int voltscale_method)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
switch (voltscale_method) {
case VOLTSCALE_VPFORCEUPDATE:
- vdd->volt_scale = vp_forceupdate_scale_voltage;
+ voltdm->scale = omap_vp_forceupdate_scale;
return;
case VOLTSCALE_VCBYPASS:
- vdd->volt_scale = vc_bypass_scale_voltage;
+ voltdm->scale = omap_vc_bypass_scale_voltage;
return;
default:
pr_warning("%s: Trying to change the method of voltage scaling"
@@ -1029,36 +282,63 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,
}
}
-/**
- * omap_voltage_domain_lookup() - API to get the voltage domain pointer
- * @name: Name of the voltage domain
- *
- * This API looks up in the global vdd_info struct for the
- * existence of voltage domain <name>. If it exists, the API returns
- * a pointer to the voltage domain structure corresponding to the
- * VDD<name>. Else retuns error pointer.
- */
-struct voltagedomain *omap_voltage_domain_lookup(char *name)
+/* Voltage debugfs support */
+static int vp_volt_debug_get(void *data, u64 *val)
{
- int i;
+ struct voltagedomain *voltdm = (struct voltagedomain *)data;
- if (!vdd_info) {
- pr_err("%s: Voltage driver init not yet happened.Faulting!\n",
- __func__);
- return ERR_PTR(-EINVAL);
+ if (!voltdm) {
+ pr_warning("Wrong paramater passed\n");
+ return -EINVAL;
+ }
+ *val = omap_vp_get_curr_volt(voltdm);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
+
+static int nom_volt_debug_get(void *data, u64 *val)
+{
+ struct voltagedomain *voltdm = (struct voltagedomain *) data;
+
+ if (!voltdm) {
+ pr_warning("Wrong paramater passed\n");
+ return -EINVAL;
}
+ *val = omap_voltage_get_nom_volt(voltdm);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
+ "%llu\n");
+
+static void __init voltdm_debugfs_init(struct dentry *voltage_dir,
+ struct voltagedomain *voltdm)
+{
+ char *name;
+
+ name = kasprintf(GFP_KERNEL, "vdd_%s", voltdm->name);
if (!name) {
- pr_err("%s: No name to get the votage domain!\n", __func__);
- return ERR_PTR(-EINVAL);
+ pr_warning("%s:vdd_%s: no mem for debugfs\n", __func__,
+ voltdm->name);
+ return;
}
- for (i = 0; i < nr_scalable_vdd; i++) {
- if (!(strcmp(name, vdd_info[i]->voltdm.name)))
- return &vdd_info[i]->voltdm;
+ voltdm->debug_dir = debugfs_create_dir(name, voltage_dir);
+ kfree(name);
+ if (IS_ERR_OR_NULL(voltdm->debug_dir)) {
+ pr_warning("%s: Unable to create debugfs directory for"
+ " vdd_%s\n", __func__, voltdm->name);
+ voltdm->debug_dir = NULL;
+ return;
}
- return ERR_PTR(-EINVAL);
+ (void) debugfs_create_file("curr_vp_volt", S_IRUGO, voltdm->debug_dir,
+ (void *) voltdm, &vp_volt_debug_fops);
+ (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
+ voltdm->debug_dir, (void *) voltdm,
+ &nom_volt_debug_fops);
}
/**
@@ -1070,37 +350,179 @@ struct voltagedomain *omap_voltage_domain_lookup(char *name)
*/
int __init omap_voltage_late_init(void)
{
- int i;
+ struct voltagedomain *voltdm;
+ struct dentry *voltage_dir;
- if (!vdd_info) {
+ if (list_empty(&voltdm_list)) {
pr_err("%s: Voltage driver support not added\n",
__func__);
return -EINVAL;
}
voltage_dir = debugfs_create_dir("voltage", NULL);
- if (IS_ERR(voltage_dir))
- pr_err("%s: Unable to create voltage debugfs main dir\n",
- __func__);
- for (i = 0; i < nr_scalable_vdd; i++) {
- if (omap_vdd_data_configure(vdd_info[i]))
+
+ list_for_each_entry(voltdm, &voltdm_list, node) {
+ if (!voltdm->scalable)
continue;
- omap_vc_init(vdd_info[i]);
- vp_init(vdd_info[i]);
- vdd_debugfs_init(vdd_info[i]);
+
+ if (voltdm->vdd) {
+ if (omap_vdd_data_configure(voltdm))
+ continue;
+ omap_vp_init(voltdm);
+ }
+
+ if (voltdm->vc)
+ omap_vc_init_channel(voltdm);
+
+ if (voltage_dir)
+ voltdm_debugfs_init(voltage_dir, voltdm);
+
}
return 0;
}
-/* XXX document */
-int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_ocp_mod,
- struct omap_vdd_info *omap_vdd_array[],
- u8 omap_vdd_count)
+static struct voltagedomain *_voltdm_lookup(const char *name)
{
- prm_mod_offs = prm_mod;
- prm_irqst_ocp_mod_offs = prm_irqst_ocp_mod;
- vdd_info = omap_vdd_array;
- nr_scalable_vdd = omap_vdd_count;
+ struct voltagedomain *voltdm, *temp_voltdm;
+
+ voltdm = NULL;
+
+ list_for_each_entry(temp_voltdm, &voltdm_list, node) {
+ if (!strcmp(name, temp_voltdm->name)) {
+ voltdm = temp_voltdm;
+ break;
+ }
+ }
+
+ return voltdm;
+}
+
+/**
+ * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
+ * @voltdm: struct voltagedomain * to add the powerdomain to
+ * @pwrdm: struct powerdomain * to associate with a voltagedomain
+ *
+ * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This
+ * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if
+ * presented with invalid pointers; -ENOMEM if memory could not be allocated;
+ * or 0 upon success.
+ */
+int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
+{
+ if (!voltdm || !pwrdm)
+ return -EINVAL;
+
+ pr_debug("voltagedomain: associating powerdomain %s with voltagedomain "
+ "%s\n", pwrdm->name, voltdm->name);
+
+ list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
+
return 0;
}
+
+/**
+ * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
+ * @voltdm: struct voltagedomain * to iterate over
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each powerdomain in the
+ * voltagedomain @voltdm. Returns -EINVAL if presented with invalid
+ * pointers; or passes along the last return value of the callback
+ * function, which should be 0 for success or anything else to
+ * indicate failure.
+ */
+int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
+ int (*fn)(struct voltagedomain *voltdm,
+ struct powerdomain *pwrdm))
+{
+ struct powerdomain *pwrdm;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
+ ret = (*fn)(voltdm, pwrdm);
+
+ return ret;
+}
+
+/**
+ * voltdm_for_each - call function on each registered voltagedomain
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each registered voltagedomain.
+ * The callback function @fn can return anything but 0 to bail out
+ * early from the iterator. Returns the last return value of the
+ * callback function, which should be 0 for success or anything else
+ * to indicate failure; or -EINVAL if the function pointer is null.
+ */
+int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
+ void *user)
+{
+ struct voltagedomain *temp_voltdm;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ list_for_each_entry(temp_voltdm, &voltdm_list, node) {
+ ret = (*fn)(temp_voltdm, user);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int _voltdm_register(struct voltagedomain *voltdm)
+{
+ if (!voltdm || !voltdm->name)
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&voltdm->pwrdm_list);
+ list_add(&voltdm->node, &voltdm_list);
+
+ pr_debug("voltagedomain: registered %s\n", voltdm->name);
+
+ return 0;
+}
+
+/**
+ * voltdm_lookup - look up a voltagedomain by name, return a pointer
+ * @name: name of voltagedomain
+ *
+ * Find a registered voltagedomain by its name @name. Returns a pointer
+ * to the struct voltagedomain if found, or NULL otherwise.
+ */
+struct voltagedomain *voltdm_lookup(const char *name)
+{
+ struct voltagedomain *voltdm ;
+
+ if (!name)
+ return NULL;
+
+ voltdm = _voltdm_lookup(name);
+
+ return voltdm;
+}
+
+/**
+ * voltdm_init - set up the voltagedomain layer
+ * @voltdm_list: array of struct voltagedomain pointers to register
+ *
+ * Loop through the array of voltagedomains @voltdm_list, registering all
+ * that are available on the current CPU. If voltdm_list is supplied
+ * and not null, all of the referenced voltagedomains will be
+ * registered. No return value.
+ */
+void voltdm_init(struct voltagedomain **voltdms)
+{
+ struct voltagedomain **v;
+
+ if (voltdms) {
+ for (v = voltdms; *v; v++)
+ _voltdm_register(*v);
+ }
+}
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index e9f5408..c2b4f3b 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -19,6 +19,8 @@
#include "vc.h"
#include "vp.h"
+struct powerdomain;
+
/* XXX document */
#define VOLTSCALE_VPFORCEUPDATE 1
#define VOLTSCALE_VCBYPASS 2
@@ -31,8 +33,10 @@
#define OMAP3_VOLTOFFSET 0xff
#define OMAP3_VOLTSETUP2 0xff
+struct omap_vdd_info;
+
/**
- * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield
+ * struct omap_vfsm_instance - per-voltage manager FSM register/bitfield
* data
* @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
* @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
@@ -42,7 +46,7 @@
* XXX It is not necessary to have both a _mask and a _shift for the same
* bitfield - remove one!
*/
-struct omap_vfsm_instance_data {
+struct omap_vfsm_instance {
u32 voltsetup_mask;
u8 voltsetup_reg;
u8 voltsetup_shift;
@@ -50,11 +54,41 @@ struct omap_vfsm_instance_data {
/**
* struct voltagedomain - omap voltage domain global structure.
- * @name: Name of the voltage domain which can be used as a unique
- * identifier.
+ * @name: Name of the voltage domain which can be used as a unique identifier.
+ * @scalable: Whether or not this voltage domain is scalable
+ * @node: list_head linking all voltage domains
+ * @pwrdm_node: list_head linking all powerdomains in this voltagedomain
+ * @vdd: to be removed
+ * @pwrdms: powerdomains in this voltagedomain
+ * @scale: function used to scale the voltage of the voltagedomain
+ * @curr_volt: current nominal voltage for this voltage domain
*/
struct voltagedomain {
char *name;
+ bool scalable;
+ struct list_head node;
+ struct list_head pwrdm_list;
+ struct omap_vc_channel *vc;
+ const struct omap_vfsm_instance *vfsm;
+ struct omap_vp_instance *vp;
+ struct omap_voltdm_pmic *pmic;
+
+ /* VC/VP register access functions: SoC specific */
+ u32 (*read) (u8 offset);
+ void (*write) (u32 val, u8 offset);
+ u32 (*rmw)(u32 mask, u32 bits, u8 offset);
+
+ union {
+ const char *name;
+ u32 rate;
+ } sys_clk;
+
+ int (*scale) (struct voltagedomain *voltdm,
+ unsigned long target_volt);
+ u32 curr_volt;
+
+ struct omap_vdd_info *vdd;
+ struct dentry *debug_dir;
};
/**
@@ -76,14 +110,52 @@ struct omap_volt_data {
u8 vp_errgain;
};
+/*
+ * Introduced in OMAP4, is a concept of a default channel - in OMAP4, this
+ * channel is MPU, all other domains such as IVA/CORE, could optionally
+ * link their i2c reg configuration to use MPU channel's configuration if
+ * required. To do this, mark in the PMIC structure's
+ * i2c_slave_addr, volt_reg_addr,cmd_reg_addr with this macro.
+ */
+#define USE_DEFAULT_CHANNEL_I2C_PARAM 0x8000
+
+/* Min and max voltages from OMAP perspective */
+#define OMAP3430_VP1_VLIMITTO_VDDMIN 850000
+#define OMAP3430_VP1_VLIMITTO_VDDMAX 1425000
+#define OMAP3430_VP2_VLIMITTO_VDDMIN 900000
+#define OMAP3430_VP2_VLIMITTO_VDDMAX 1150000
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN 900000
+#define OMAP3630_VP1_VLIMITTO_VDDMAX 1350000
+#define OMAP3630_VP2_VLIMITTO_VDDMIN 900000
+#define OMAP3630_VP2_VLIMITTO_VDDMAX 1200000
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 830000
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 1410000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 830000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 1260000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 830000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 1200000
+
+#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
+#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
+#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
+#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
+
/**
- * struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
+ * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
* @slew_rate: PMIC slew rate (in uv/us)
* @step_size: PMIC voltage step size (in uv)
+ * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC
+ * @i2c_mcode: master code value for I2C high-speed preamble transmission
* @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
* @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
+ * @i2c_hscll_low: PMIC interface speed config for highspeed mode (T low)
+ * @i2c_hscll_high: PMIC interface speed config for highspeed mode (T high)
+ * @i2c_scll_low: PMIC interface speed config for fullspeed mode (T low)
+ * @i2c_scll_high: PMIC interface speed config for fullspeed mode (T high)
*/
-struct omap_volt_pmic_info {
+struct omap_voltdm_pmic {
int slew_rate;
int step_size;
u32 on_volt;
@@ -94,78 +166,78 @@ struct omap_volt_pmic_info {
u8 vp_erroroffset;
u8 vp_vstepmin;
u8 vp_vstepmax;
- u8 vp_vddmin;
- u8 vp_vddmax;
+ u32 vp_vddmin;
+ u32 vp_vddmax;
u8 vp_timeout_us;
- u8 i2c_slave_addr;
- u8 pmic_reg;
+ u16 i2c_slave_addr;
+ u16 volt_reg_addr;
+ u16 cmd_reg_addr;
+ bool i2c_high_speed;
+ u8 i2c_hscll_low;
+ u8 i2c_hscll_high;
+ u8 i2c_scll_low;
+ u8 i2c_scll_high;
+ u8 i2c_mcode;
unsigned long (*vsel_to_uv) (const u8 vsel);
u8 (*uv_to_vsel) (unsigned long uV);
};
/**
+ * struct omap_vdd_dep_volt - Map table for voltage dependencies
+ * @main_vdd_volt : The main vdd voltage
+ * @dep_vdd_volt : The voltage at which the dependent vdd should be
+ * when the main vdd is at <main_vdd_volt> voltage
+ *
+ * Table containing the parent vdd voltage and the dependent vdd voltage
+ * corresponding to it.
+ */
+struct omap_vdd_dep_volt {
+ u32 main_vdd_volt;
+ u32 dep_vdd_volt;
+};
+
+/**
+ * struct omap_vdd_dep_info - Dependent vdd info
+ * @name : Dependent vdd name
+ * @_dep_voltdm : internal structure meant to prevent multiple lookups
+ * @dep_table : Table containing the dependent vdd voltage
+ * corresponding to every main vdd voltage.
+ * @nr_dep_entries : number of dependency voltage entries
+ */
+struct omap_vdd_dep_info {
+ char *name;
+ struct voltagedomain *_dep_voltdm;
+ struct omap_vdd_dep_volt *dep_table;
+ int nr_dep_entries;
+};
+
+/**
* omap_vdd_info - Per Voltage Domain info
*
* @volt_data : voltage table having the distinct voltages supported
* by the domain and other associated per voltage data.
- * @pmic_info : pmic specific parameters which should be populted by
- * the pmic drivers.
- * @vp_data : the register values, shifts, masks for various
- * vp registers
- * @vp_rt_data : VP data derived at runtime, not predefined
- * @vc_data : structure containing various various vc registers,
- * shifts, masks etc.
- * @vfsm : voltage manager FSM data
- * @voltdm : pointer to the voltage domain structure
- * @debug_dir : debug directory for this voltage domain.
- * @curr_volt : current voltage for this vdd.
- * @vp_enabled : flag to keep track of whether vp is enabled or not
- * @volt_scale : API to scale the voltage of the vdd.
+ * @dep_vdd_info : Array ending with a 0 terminator for dependency
+ * voltage information.
*/
struct omap_vdd_info {
struct omap_volt_data *volt_data;
- struct omap_volt_pmic_info *pmic_info;
- struct omap_vp_instance_data *vp_data;
- struct omap_vp_runtime_data vp_rt_data;
- struct omap_vc_instance_data *vc_data;
- const struct omap_vfsm_instance_data *vfsm;
- struct voltagedomain voltdm;
- struct dentry *debug_dir;
- u32 curr_volt;
- bool vp_enabled;
- u32 (*read_reg) (u16 mod, u8 offset);
- void (*write_reg) (u32 val, u16 mod, u8 offset);
- int (*volt_scale) (struct omap_vdd_info *vdd,
- unsigned long target_volt);
+ struct omap_vdd_dep_info *dep_vdd_info;
};
-unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
-void omap_vp_enable(struct voltagedomain *voltdm);
-void omap_vp_disable(struct voltagedomain *voltdm);
-int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
- unsigned long target_volt);
-void omap_voltage_reset(struct voltagedomain *voltdm);
void omap_voltage_get_volttable(struct voltagedomain *voltdm,
struct omap_volt_data **volt_data);
struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
unsigned long volt);
unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
-struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
-int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_mod,
- struct omap_vdd_info *omap_vdd_array[],
- u8 omap_vdd_count);
#ifdef CONFIG_PM
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
- struct omap_volt_pmic_info *pmic_info);
+ struct omap_voltdm_pmic *pmic);
void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method);
-/* API to get the voltagedomain pointer */
-struct voltagedomain *omap_voltage_domain_lookup(char *name);
-
int omap_voltage_late_init(void);
#else
static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
- struct omap_volt_pmic_info *pmic_info)
+ struct omap_voltdm_pmic *pmic)
{
return -EINVAL;
}
@@ -175,10 +247,20 @@ static inline int omap_voltage_late_init(void)
{
return -EINVAL;
}
-static inline struct voltagedomain *omap_voltage_domain_lookup(char *name)
-{
- return ERR_PTR(-EINVAL);
-}
#endif
+extern void omap2xxx_voltagedomains_init(void);
+extern void omap3xxx_voltagedomains_init(void);
+extern void omap44xx_voltagedomains_init(void);
+
+struct voltagedomain *voltdm_lookup(const char *name);
+void voltdm_init(struct voltagedomain **voltdm_list);
+int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm);
+int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
+ void *user);
+int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
+ int (*fn)(struct voltagedomain *voltdm,
+ struct powerdomain *pwrdm));
+int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
+void voltdm_reset(struct voltagedomain *voltdm);
#endif
diff --git a/arch/arm/mach-omap2/voltagedomains2xxx_data.c b/arch/arm/mach-omap2/voltagedomains2xxx_data.c
new file mode 100644
index 0000000..69ff261
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains2xxx_data.c
@@ -0,0 +1,32 @@
+/*
+ * OMAP3 voltage domain data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "voltage.h"
+
+static struct voltagedomain omap2_voltdm_core = {
+ .name = "core",
+};
+
+static struct voltagedomain omap2_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+static struct voltagedomain *voltagedomains_omap2[] __initdata = {
+ &omap2_voltdm_core,
+ &omap2_voltdm_wkup,
+ NULL,
+};
+
+void __init omap2xxx_voltagedomains_init(void)
+{
+ voltdm_init(voltagedomains_omap2);
+}
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index def230f..8264d15 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -31,50 +31,63 @@
* VDD data
*/
-static const struct omap_vfsm_instance_data omap3_vdd1_vfsm_data = {
+static const struct omap_vfsm_instance omap3_vdd1_vfsm = {
.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT,
.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
};
-static struct omap_vdd_info omap3_vdd1_info = {
- .vp_data = &omap3_vp1_data,
- .vc_data = &omap3_vc1_data,
- .vfsm = &omap3_vdd1_vfsm_data,
- .voltdm = {
- .name = "mpu",
- },
-};
+static struct omap_vdd_info omap3_vdd1_info;
-static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = {
+static const struct omap_vfsm_instance omap3_vdd2_vfsm = {
.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
.voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT,
.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
};
-static struct omap_vdd_info omap3_vdd2_info = {
- .vp_data = &omap3_vp2_data,
- .vc_data = &omap3_vc2_data,
- .vfsm = &omap3_vdd2_vfsm_data,
- .voltdm = {
- .name = "core",
- },
+static struct omap_vdd_info omap3_vdd2_info;
+
+static struct voltagedomain omap3_voltdm_mpu = {
+ .name = "mpu_iva",
+ .scalable = true,
+ .read = omap3_prm_vcvp_read,
+ .write = omap3_prm_vcvp_write,
+ .rmw = omap3_prm_vcvp_rmw,
+ .vc = &omap3_vc_mpu,
+ .vfsm = &omap3_vdd1_vfsm,
+ .vp = &omap3_vp_mpu,
+ .vdd = &omap3_vdd1_info,
};
-/* OMAP3 VDD structures */
-static struct omap_vdd_info *omap3_vdd_info[] = {
- &omap3_vdd1_info,
- &omap3_vdd2_info,
+static struct voltagedomain omap3_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap3_prm_vcvp_read,
+ .write = omap3_prm_vcvp_write,
+ .rmw = omap3_prm_vcvp_rmw,
+ .vc = &omap3_vc_core,
+ .vfsm = &omap3_vdd2_vfsm,
+ .vp = &omap3_vp_core,
+ .vdd = &omap3_vdd2_info,
};
-/* OMAP3 specific voltage init functions */
-static int __init omap3xxx_voltage_early_init(void)
-{
- s16 prm_mod = OMAP3430_GR_MOD;
- s16 prm_irqst_ocp_mod = OCP_MOD;
+static struct voltagedomain omap3_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+static struct voltagedomain *voltagedomains_omap3[] __initdata = {
+ &omap3_voltdm_mpu,
+ &omap3_voltdm_core,
+ &omap3_voltdm_wkup,
+ NULL,
+};
+
+static const char *sys_clk_name __initdata = "sys_ck";
- if (!cpu_is_omap34xx())
- return 0;
+void __init omap3xxx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ int i;
/*
* XXX Will depend on the process, validation, and binning
@@ -83,13 +96,16 @@ static int __init omap3xxx_voltage_early_init(void)
if (cpu_is_omap3630()) {
omap3_vdd1_info.volt_data = omap36xx_vddmpu_volt_data;
omap3_vdd2_info.volt_data = omap36xx_vddcore_volt_data;
+ omap3_vdd1_info.dep_vdd_info = omap36xx_vddmpu_dep_info;
+
} else {
omap3_vdd1_info.volt_data = omap34xx_vddmpu_volt_data;
omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;
+ omap3_vdd1_info.dep_vdd_info = omap34xx_vddmpu_dep_info;
}
- return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
- omap3_vdd_info,
- ARRAY_SIZE(omap3_vdd_info));
+ for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
+
+ voltdm_init(voltagedomains_omap3);
};
-core_initcall(omap3xxx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index cb64996..5fce5ad 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/init.h>
+#include <linux/clk.h>
#include <plat/common.h>
@@ -32,71 +33,101 @@
#include "vc.h"
#include "vp.h"
-static const struct omap_vfsm_instance_data omap4_vdd_mpu_vfsm_data = {
+static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = {
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
};
-static struct omap_vdd_info omap4_vdd_mpu_info = {
- .vp_data = &omap4_vp_mpu_data,
- .vc_data = &omap4_vc_mpu_data,
- .vfsm = &omap4_vdd_mpu_vfsm_data,
- .voltdm = {
- .name = "mpu",
- },
-};
+static struct omap_vdd_info omap4_vdd_mpu_info;
-static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = {
+static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = {
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
};
-static struct omap_vdd_info omap4_vdd_iva_info = {
- .vp_data = &omap4_vp_iva_data,
- .vc_data = &omap4_vc_iva_data,
- .vfsm = &omap4_vdd_iva_vfsm_data,
- .voltdm = {
- .name = "iva",
- },
-};
+static struct omap_vdd_info omap4_vdd_iva_info;
-static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = {
+static const struct omap_vfsm_instance omap4_vdd_core_vfsm = {
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
};
-static struct omap_vdd_info omap4_vdd_core_info = {
- .vp_data = &omap4_vp_core_data,
- .vc_data = &omap4_vc_core_data,
- .vfsm = &omap4_vdd_core_vfsm_data,
- .voltdm = {
- .name = "core",
- },
+static struct omap_vdd_info omap4_vdd_core_info;
+
+static struct voltagedomain omap4_voltdm_mpu = {
+ .name = "mpu",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_mpu,
+ .vfsm = &omap4_vdd_mpu_vfsm,
+ .vp = &omap4_vp_mpu,
+ .vdd = &omap4_vdd_mpu_info,
+};
+
+static struct voltagedomain omap4_voltdm_iva = {
+ .name = "iva",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_iva,
+ .vfsm = &omap4_vdd_iva_vfsm,
+ .vp = &omap4_vp_iva,
+ .vdd = &omap4_vdd_iva_info,
};
-/* OMAP4 VDD structures */
-static struct omap_vdd_info *omap4_vdd_info[] = {
- &omap4_vdd_mpu_info,
- &omap4_vdd_iva_info,
- &omap4_vdd_core_info,
+static struct voltagedomain omap4_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_core,
+ .vfsm = &omap4_vdd_core_vfsm,
+ .vp = &omap4_vp_core,
+ .vdd = &omap4_vdd_core_info,
};
-/* OMAP4 specific voltage init functions */
-static int __init omap44xx_voltage_early_init(void)
-{
- s16 prm_mod = OMAP4430_PRM_DEVICE_INST;
- s16 prm_irqst_ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
+static struct voltagedomain omap4_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+static struct voltagedomain *voltagedomains_omap4[] __initdata = {
+ &omap4_voltdm_mpu,
+ &omap4_voltdm_iva,
+ &omap4_voltdm_core,
+ &omap4_voltdm_wkup,
+ NULL,
+};
- if (!cpu_is_omap44xx())
- return 0;
+static const char *sys_clk_name __initdata = "sys_clkin_ck";
+
+void __init omap44xx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ int i;
/*
* XXX Will depend on the process, validation, and binning
* for the currently-running IC
*/
- omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
- omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
- omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+ if (cpu_is_omap443x()) {
+ omap4_vdd_mpu_info.volt_data = omap443x_vdd_mpu_volt_data;
+ omap4_vdd_iva_info.volt_data = omap443x_vdd_iva_volt_data;
+ omap4_vdd_core_info.volt_data = omap443x_vdd_core_volt_data;
+ omap4_vdd_mpu_info.dep_vdd_info = omap443x_vddmpu_dep_info;
+ omap4_vdd_iva_info.dep_vdd_info = omap443x_vddiva_dep_info;
+ } else if (cpu_is_omap446x()) {
+ omap4_vdd_mpu_info.volt_data = omap446x_vdd_mpu_volt_data;
+ omap4_vdd_iva_info.volt_data = omap446x_vdd_iva_volt_data;
+ omap4_vdd_core_info.volt_data = omap446x_vdd_core_volt_data;
+ omap4_vdd_mpu_info.dep_vdd_info = omap446x_vddmpu_dep_info;
+ omap4_vdd_iva_info.dep_vdd_info = omap446x_vddiva_dep_info;
+ } else {
+ return;
+ }
+
+ for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
- return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
- omap4_vdd_info,
- ARRAY_SIZE(omap4_vdd_info));
+ voltdm_init(voltagedomains_omap4);
};
-core_initcall(omap44xx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
new file mode 100644
index 0000000..4677921
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.c
@@ -0,0 +1,329 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "voltage.h"
+#include "vp.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+
+static void vp_latch_vsel(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 vpconfig;
+ unsigned long uvdc;
+ char vsel;
+
+ uvdc = omap_voltage_get_nom_volt(voltdm);
+ if (!uvdc) {
+ pr_warning("%s: unable to find current voltage for vdd_%s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+ pr_warning("%s: PMIC function to convert voltage in uV to"
+ " vsel not registered\n", __func__);
+ return;
+ }
+
+ vsel = voltdm->pmic->uv_to_vsel(uvdc);
+
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
+ vp->common->vpconfig_initvdd);
+ vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask);
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ voltdm->write((vpconfig | vp->common->vpconfig_initvdd),
+ vp->vpconfig);
+
+ /* Clear initVDD copy trigger bit */
+ voltdm->write(vpconfig, vp->vpconfig);
+}
+
+/* Generic voltage init functions */
+void __init omap_vp_init(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 val, sys_clk_rate, timeout, waittime;
+ u32 vddmin, vddmax, vstepmin, vstepmax;
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vp->enabled = false;
+
+ /* Divide to avoid overflow */
+ sys_clk_rate = voltdm->sys_clk.rate / 1000;
+
+ timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
+ vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
+ vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
+
+ waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
+ sys_clk_rate) / 1000;
+ vstepmin = voltdm->pmic->vp_vstepmin;
+ vstepmax = voltdm->pmic->vp_vstepmax;
+
+ /*
+ * VP_CONFIG: error gain is not set here, it will be updated
+ * on each scale, based on OPP.
+ */
+ val = (voltdm->pmic->vp_erroroffset <<
+ __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) |
+ vp->common->vpconfig_timeouten;
+ voltdm->write(val, vp->vpconfig);
+
+ /* VSTEPMIN */
+ val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) |
+ (vstepmin << vp->common->vstepmin_stepmin_shift);
+ voltdm->write(val, vp->vstepmin);
+
+ /* VSTEPMAX */
+ val = (vstepmax << vp->common->vstepmax_stepmax_shift) |
+ (waittime << vp->common->vstepmax_smpswaittimemax_shift);
+ voltdm->write(val, vp->vstepmax);
+
+ /* VLIMITTO */
+ val = (vddmax << vp->common->vlimitto_vddmax_shift) |
+ (vddmin << vp->common->vlimitto_vddmin_shift) |
+ (timeout << vp->common->vlimitto_timeout_shift);
+ voltdm->write(val, vp->vlimitto);
+}
+
+int omap_vp_update_errorgain(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_volt_data *volt_data;
+
+ /* Get volt_data corresponding to target_volt */
+ volt_data = omap_voltage_get_voltdata(voltdm, target_volt);
+ if (IS_ERR(volt_data))
+ return -EINVAL;
+
+ /* Setting vp errorgain based on the voltage */
+ voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask,
+ volt_data->vp_errgain <<
+ __ffs(voltdm->vp->common->vpconfig_errorgain_mask),
+ voltdm->vp->vpconfig);
+
+ return 0;
+}
+
+/* VP force update method of voltage scaling */
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 vpconfig;
+ u8 target_vsel, current_vsel;
+ int ret, timeout = 0;
+
+ ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ /*
+ * Clear all pending TransactionDone interrupt/status. Typical latency
+ * is <3us
+ */
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vp->common->ops->clear_txdone(vp->id);
+ if (!vp->common->ops->check_txdone(vp->id))
+ break;
+ udelay(1);
+ }
+ if (timeout >= VP_TRANXDONE_TIMEOUT) {
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
+ "Voltage change aborted", __func__, voltdm->name);
+ return -ETIMEDOUT;
+ }
+
+ /* Configure for VP-Force Update */
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~(vp->common->vpconfig_initvdd |
+ vp->common->vpconfig_forceupdate |
+ vp->common->vpconfig_initvoltage_mask);
+ vpconfig |= ((target_vsel <<
+ __ffs(vp->common->vpconfig_initvoltage_mask)));
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ vpconfig |= vp->common->vpconfig_initvdd;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /* Force update of voltage */
+ vpconfig |= vp->common->vpconfig_forceupdate;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /*
+ * Wait for TransactionDone. Typical latency is <200us.
+ * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+ */
+ timeout = 0;
+ omap_test_timeout(vp->common->ops->check_txdone(vp->id),
+ VP_TRANXDONE_TIMEOUT, timeout);
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
+ "TRANXDONE never got set after the voltage update\n",
+ __func__, voltdm->name);
+
+ omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+
+ /*
+ * Disable TransactionDone interrupt , clear all status, clear
+ * control registers
+ */
+ timeout = 0;
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vp->common->ops->clear_txdone(vp->id);
+ if (!vp->common->ops->check_txdone(vp->id))
+ break;
+ udelay(1);
+ }
+
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
+ "to clear the TRANXDONE status\n",
+ __func__, voltdm->name);
+
+ vpconfig = voltdm->read(vp->vpconfig);
+ /* Clear initVDD copy trigger bit */
+ vpconfig &= ~vp->common->vpconfig_initvdd;
+ voltdm->write(vpconfig, vp->vpconfig);
+ /* Clear force bit */
+ vpconfig &= ~vp->common->vpconfig_forceupdate;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ return 0;
+}
+
+/**
+ * omap_vp_get_curr_volt() - API to get the current vp voltage.
+ * @voltdm: pointer to the VDD.
+ *
+ * This API returns the current voltage for the specified voltage processor
+ */
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u8 curr_vsel;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return 0;
+ }
+
+ if (!voltdm->read) {
+ pr_err("%s: No read API for reading vdd_%s regs\n",
+ __func__, voltdm->name);
+ return 0;
+ }
+
+ curr_vsel = (voltdm->read(vp->voltage) & vp->common->vpvoltage_mask)
+ >> __ffs(vp->common->vpvoltage_mask);
+
+ if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) {
+ pr_warning("%s: PMIC function to convert vsel to voltage"
+ "in uV not registerd\n", __func__);
+ return 0;
+ }
+
+ return voltdm->pmic->vsel_to_uv(curr_vsel);
+}
+
+/**
+ * omap_vp_enable() - API to enable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be enabled.
+ *
+ * This API enables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_enable(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp;
+ u32 vpconfig;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vp = voltdm->vp;
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* If VP is already enabled, do nothing. Return */
+ if (vp->enabled)
+ return;
+
+ vp_latch_vsel(voltdm);
+
+ /* Enable VP */
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig |= vp->common->vpconfig_vpenable;
+ voltdm->write(vpconfig, vp->vpconfig);
+ vp->enabled = true;
+}
+
+/**
+ * omap_vp_disable() - API to disable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be disabled.
+ *
+ * This API disables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_disable(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp;
+ u32 vpconfig;
+ int timeout;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vp = voltdm->vp;
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* If VP is already disabled, do nothing. Return */
+ if (!vp->enabled) {
+ pr_warning("%s: Trying to disable VP for vdd_%s when"
+ "it is already disabled\n", __func__, voltdm->name);
+ return;
+ }
+
+ /* Disable VP */
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~vp->common->vpconfig_vpenable;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /*
+ * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+ */
+ omap_test_timeout((voltdm->read(vp->vstatus)),
+ VP_IDLE_TIMEOUT, timeout);
+
+ if (timeout >= VP_IDLE_TIMEOUT)
+ pr_warning("%s: vdd_%s idle timedout\n",
+ __func__, voltdm->name);
+
+ vp->enabled = false;
+
+ return;
+}
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
index 7ce134f..f78752b 100644
--- a/arch/arm/mach-omap2/vp.h
+++ b/arch/arm/mach-omap2/vp.h
@@ -19,44 +19,60 @@
#include <linux/kernel.h>
+struct voltagedomain;
+
+/*
+ * Voltage Processor (VP) identifiers
+ */
+#define OMAP3_VP_VDD_MPU_ID 0
+#define OMAP3_VP_VDD_CORE_ID 1
+#define OMAP4_VP_VDD_CORE_ID 0
+#define OMAP4_VP_VDD_IVA_ID 1
+#define OMAP4_VP_VDD_MPU_ID 2
+
/* XXX document */
#define VP_IDLE_TIMEOUT 200
#define VP_TRANXDONE_TIMEOUT 300
+/**
+ * struct omap_vp_ops - per-VP operations
+ * @check_txdone: check for VP transaction done
+ * @clear_txdone: clear VP transaction done status
+ */
+struct omap_vp_ops {
+ u32 (*check_txdone)(u8 vp_id);
+ void (*clear_txdone)(u8 vp_id);
+};
/**
- * struct omap_vp_common_data - register data common to all VDDs
+ * struct omap_vp_common - register data common to all VDDs
+ * @vpconfig_erroroffset_mask: ERROROFFSET bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
- * @vpconfig_timeouten_mask: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_timeouten: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg
* @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg
* @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg
- * @vpconfig_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
- * @vpconfig_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
- * @vpconfig_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
- * @vpconfig_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
- * @vpconfig_vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
- * @vpconfig_vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
- * @vpconfig_vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
- *
- * XXX It it not necessary to have both a mask and a shift for the same
- * bitfield - remove one
- * XXX Many of these fields are wrongly named -- e.g., vpconfig_smps* -- fix!
+ * @vstepmin_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
+ * @vstepmin_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
+ * @vstepmax_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
+ * @vstepmax_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
+ * @vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
+ * @vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
+ * @vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
+ * @vpvoltage_mask: VPVOLTAGE field mask in PRM_VP*_VOLTAGE reg
*/
-struct omap_vp_common_data {
+struct omap_vp_common {
+ u32 vpconfig_erroroffset_mask;
u32 vpconfig_errorgain_mask;
u32 vpconfig_initvoltage_mask;
- u32 vpconfig_timeouten;
- u32 vpconfig_initvdd;
- u32 vpconfig_forceupdate;
- u32 vpconfig_vpenable;
- u8 vpconfig_erroroffset_shift;
- u8 vpconfig_errorgain_shift;
- u8 vpconfig_initvoltage_shift;
+ u8 vpconfig_timeouten;
+ u8 vpconfig_initvdd;
+ u8 vpconfig_forceupdate;
+ u8 vpconfig_vpenable;
u8 vstepmin_stepmin_shift;
u8 vstepmin_smpswaittimemin_shift;
u8 vstepmax_stepmax_shift;
@@ -64,80 +80,49 @@ struct omap_vp_common_data {
u8 vlimitto_vddmin_shift;
u8 vlimitto_vddmax_shift;
u8 vlimitto_timeout_shift;
-};
+ u8 vpvoltage_mask;
-/**
- * struct omap_vp_prm_irqst_data - PRM_IRQSTATUS_MPU.VP_TRANXDONE_ST data
- * @prm_irqst_reg: reg offset for PRM_IRQSTATUS_MPU from top of PRM
- * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
- *
- * XXX prm_irqst_reg does not belong here
- * XXX Note that on OMAP3, VP_TRANXDONE interrupt may not work due to a
- * hardware bug
- * XXX This structure is probably not needed
- */
-struct omap_vp_prm_irqst_data {
- u8 prm_irqst_reg;
- u32 tranxdone_status;
+ const struct omap_vp_ops *ops;
};
/**
- * struct omap_vp_instance_data - VP register offsets (per-VDD)
- * @vp_common: pointer to struct omap_vp_common_data * for this SoC
- * @prm_irqst_data: pointer to struct omap_vp_prm_irqst_data for this VDD
+ * struct omap_vp_instance - VP register offsets (per-VDD)
+ * @common: pointer to struct omap_vp_common * for this SoC
* @vpconfig: PRM_VP*_CONFIG reg offset from PRM start
* @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start
* @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start
* @vstatus: PRM_VP*_VSTATUS reg offset from PRM start
* @voltage: PRM_VP*_VOLTAGE reg offset from PRM start
+ * @enabled: flag to keep track of whether vp is enabled or not
*
* XXX vp_common is probably not needed since it is per-SoC
*/
-struct omap_vp_instance_data {
- const struct omap_vp_common_data *vp_common;
- const struct omap_vp_prm_irqst_data *prm_irqst_data;
+struct omap_vp_instance {
+ const struct omap_vp_common *common;
u8 vpconfig;
u8 vstepmin;
u8 vstepmax;
u8 vlimitto;
u8 vstatus;
u8 voltage;
+ u8 id;
+ bool enabled;
};
-/**
- * struct omap_vp_runtime_data - VP data populated at runtime by code
- * @vpconfig_erroroffset: value of ERROROFFSET bitfield in PRM_VP*_CONFIG
- * @vpconfig_errorgain: value of ERRORGAIN bitfield in PRM_VP*_CONFIG
- * @vstepmin_smpswaittimemin: value of SMPSWAITTIMEMIN bitfield in PRM_VP*_VSTEPMIN
- * @vstepmax_smpswaittimemax: value of SMPSWAITTIMEMAX bitfield in PRM_VP*_VSTEPMAX
- * @vlimitto_timeout: value of TIMEOUT bitfield in PRM_VP*_VLIMITTO
- * @vstepmin_stepmin: value of VSTEPMIN bitfield in PRM_VP*_VSTEPMIN
- * @vstepmax_stepmax: value of VSTEPMAX bitfield in PRM_VP*_VSTEPMAX
- * @vlimitto_vddmin: value of VDDMIN bitfield in PRM_VP*_VLIMITTO
- * @vlimitto_vddmax: value of VDDMAX bitfield in PRM_VP*_VLIMITTO
- *
- * XXX Is this structure really needed? Why not just program the
- * device directly? They are in PRM space, therefore in the WKUP
- * powerdomain, so register contents should not be lost in off-mode.
- * XXX Some of these fields are incorrectly named, e.g., vstep*
- */
-struct omap_vp_runtime_data {
- u32 vpconfig_erroroffset;
- u16 vpconfig_errorgain;
- u16 vstepmin_smpswaittimemin;
- u16 vstepmax_smpswaittimemax;
- u16 vlimitto_timeout;
- u8 vstepmin_stepmin;
- u8 vstepmax_stepmax;
- u8 vlimitto_vddmin;
- u8 vlimitto_vddmax;
-};
+extern struct omap_vp_instance omap3_vp_mpu;
+extern struct omap_vp_instance omap3_vp_core;
-extern struct omap_vp_instance_data omap3_vp1_data;
-extern struct omap_vp_instance_data omap3_vp2_data;
+extern struct omap_vp_instance omap4_vp_mpu;
+extern struct omap_vp_instance omap4_vp_iva;
+extern struct omap_vp_instance omap4_vp_core;
-extern struct omap_vp_instance_data omap4_vp_mpu_data;
-extern struct omap_vp_instance_data omap4_vp_iva_data;
-extern struct omap_vp_instance_data omap4_vp_core_data;
+void omap_vp_init(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+int omap_vp_update_errorgain(struct voltagedomain *voltdm,
+ unsigned long target_volt);
#endif
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
index 6452170..260c554 100644
--- a/arch/arm/mach-omap2/vp3xxx_data.c
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -25,16 +25,20 @@
#include "voltage.h"
#include "vp.h"
+#include "prm2xxx_3xxx.h"
+
+static const struct omap_vp_ops omap3_vp_ops = {
+ .check_txdone = omap3_prm_vp_check_txdone,
+ .clear_txdone = omap3_prm_vp_clear_txdone,
+};
/*
* VP data common to 34xx/36xx chips
* XXX This stuff presumably belongs in the vp3xxx.c or vp.c file.
*/
-static const struct omap_vp_common_data omap3_vp_common = {
- .vpconfig_erroroffset_shift = OMAP3430_ERROROFFSET_SHIFT,
+static const struct omap_vp_common omap3_vp_common = {
+ .vpconfig_erroroffset_mask = OMAP3430_ERROROFFSET_MASK,
.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
- .vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT,
- .vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT,
.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK,
.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK,
.vpconfig_initvdd = OMAP3430_INITVDD_MASK,
@@ -47,36 +51,29 @@ static const struct omap_vp_common_data omap3_vp_common = {
.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT,
.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT,
.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT,
-};
+ .vpvoltage_mask = OMAP3430_VPVOLTAGE_MASK,
-static const struct omap_vp_prm_irqst_data omap3_vp1_prm_irqst_data = {
- .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+ .ops = &omap3_vp_ops,
};
-struct omap_vp_instance_data omap3_vp1_data = {
- .vp_common = &omap3_vp_common,
+struct omap_vp_instance omap3_vp_mpu = {
+ .id = OMAP3_VP_VDD_MPU_ID,
+ .common = &omap3_vp_common,
.vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
.vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
.vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
.vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
.vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
.voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap3_vp1_prm_irqst_data,
-};
-
-static const struct omap_vp_prm_irqst_data omap3_vp2_prm_irqst_data = {
- .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
};
-struct omap_vp_instance_data omap3_vp2_data = {
- .vp_common = &omap3_vp_common,
+struct omap_vp_instance omap3_vp_core = {
+ .id = OMAP3_VP_VDD_CORE_ID,
+ .common = &omap3_vp_common,
.vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
.vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
.vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
.vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap3_vp2_prm_irqst_data,
};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
index 65d1ad6..b4e7704 100644
--- a/arch/arm/mach-omap2/vp44xx_data.c
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -27,15 +27,18 @@
#include "vp.h"
+static const struct omap_vp_ops omap4_vp_ops = {
+ .check_txdone = omap4_prm_vp_check_txdone,
+ .clear_txdone = omap4_prm_vp_clear_txdone,
+};
+
/*
* VP data common to 44xx chips
* XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
*/
-static const struct omap_vp_common_data omap4_vp_common = {
- .vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
+static const struct omap_vp_common omap4_vp_common = {
+ .vpconfig_erroroffset_mask = OMAP4430_ERROROFFSET_MASK,
.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
- .vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
- .vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT,
.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK,
.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK,
.vpconfig_initvdd = OMAP4430_INITVDD_MASK,
@@ -48,53 +51,39 @@ static const struct omap_vp_common_data omap4_vp_common = {
.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT,
.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT,
.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT,
+ .vpvoltage_mask = OMAP4430_VPVOLTAGE_MASK,
+ .ops = &omap4_vp_ops,
};
-static const struct omap_vp_prm_irqst_data omap4_vp_mpu_prm_irqst_data = {
- .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
- .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
-};
-
-struct omap_vp_instance_data omap4_vp_mpu_data = {
- .vp_common = &omap4_vp_common,
+struct omap_vp_instance omap4_vp_mpu = {
+ .id = OMAP4_VP_VDD_MPU_ID,
+ .common = &omap4_vp_common,
.vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
.vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
.vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
.vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
.vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
.voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap4_vp_mpu_prm_irqst_data,
};
-static const struct omap_vp_prm_irqst_data omap4_vp_iva_prm_irqst_data = {
- .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
-};
-
-struct omap_vp_instance_data omap4_vp_iva_data = {
- .vp_common = &omap4_vp_common,
+struct omap_vp_instance omap4_vp_iva = {
+ .id = OMAP4_VP_VDD_IVA_ID,
+ .common = &omap4_vp_common,
.vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
.vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
.vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
.vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
.vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
.voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap4_vp_iva_prm_irqst_data,
-};
-
-static const struct omap_vp_prm_irqst_data omap4_vp_core_prm_irqst_data = {
- .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
};
-struct omap_vp_instance_data omap4_vp_core_data = {
- .vp_common = &omap4_vp_common,
+struct omap_vp_instance omap4_vp_core = {
+ .id = OMAP4_VP_VDD_CORE_ID,
+ .common = &omap4_vp_common,
.vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
.vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
.vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
.vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap4_vp_core_prm_irqst_data,
};
-
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 7fe7406..094279a 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/apm-emulation.h>
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index c95258c..1e2aba2 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -382,10 +382,8 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
}
static struct sh_mobile_sdhi_info sh_sdhi1_platdata = {
- .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
- .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
.tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
- .tmio_caps = MMC_CAP_NONREMOVABLE,
+ .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
.tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.set_pwr = ag5evm_sdhi1_set_pwr,
};
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 776f205..7e1d375 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -126,7 +126,7 @@
* ------+--------------------+--------------------+-------
* IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
* IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High
- * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Tuch Panel | Low
+ * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Touch Panel | Low
* IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low
* IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
* IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
@@ -165,10 +165,10 @@
* USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
* But don't select both drivers in same time.
* These uses same IRQ number for request_irq(), and aren't supporting
- * IRQF_SHARD / IORESOURCE_IRQ_SHAREABLE.
+ * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
*
* Actually these are old/new version of USB driver.
- * This mean its register will be broken if it supports SHARD IRQ,
+ * This mean its register will be broken if it supports shared IRQ,
*/
/*
@@ -562,7 +562,121 @@ out:
clk_put(hdmi_ick);
}
-/* USB1 (Host) */
+/* USBHS0 is connected to CN22 which takes a USB Mini-B plug
+ *
+ * The sh7372 SoC has IRQ7 set aside for USBHS0 hotplug,
+ * but on this particular board IRQ7 is already used by
+ * the touch screen. This leaves us with software polling.
+ */
+#define USBHS0_POLL_INTERVAL (HZ * 5)
+
+struct usbhs_private {
+ unsigned int usbphyaddr;
+ unsigned int usbcrcaddr;
+ struct renesas_usbhs_platform_info info;
+ struct delayed_work work;
+ struct platform_device *pdev;
+};
+
+#define usbhs_get_priv(pdev) \
+ container_of(renesas_usbhs_get_info(pdev), \
+ struct usbhs_private, info)
+
+#define usbhs_is_connected(priv) \
+ (!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
+
+static int usbhs_get_vbus(struct platform_device *pdev)
+{
+ return usbhs_is_connected(usbhs_get_priv(pdev));
+}
+
+static void usbhs_phy_reset(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ /* init phy */
+ __raw_writew(0x8a0a, priv->usbcrcaddr);
+}
+
+static int usbhs0_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static void usbhs0_work_function(struct work_struct *work)
+{
+ struct usbhs_private *priv = container_of(work, struct usbhs_private,
+ work.work);
+
+ renesas_usbhs_call_notify_hotplug(priv->pdev);
+ schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
+}
+
+static int usbhs0_hardware_init(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ priv->pdev = pdev;
+ INIT_DELAYED_WORK(&priv->work, usbhs0_work_function);
+ schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
+ return 0;
+}
+
+static void usbhs0_hardware_exit(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ cancel_delayed_work_sync(&priv->work);
+}
+
+static struct usbhs_private usbhs0_private = {
+ .usbcrcaddr = 0xe605810c, /* USBCR2 */
+ .info = {
+ .platform_callback = {
+ .hardware_init = usbhs0_hardware_init,
+ .hardware_exit = usbhs0_hardware_exit,
+ .phy_reset = usbhs_phy_reset,
+ .get_id = usbhs0_get_id,
+ .get_vbus = usbhs_get_vbus,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ },
+ },
+};
+
+static struct resource usbhs0_resources[] = {
+ [0] = {
+ .name = "USBHS0",
+ .start = 0xe6890000,
+ .end = 0xe68900e6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ca0) /* USB0_USB0I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhs0_device = {
+ .name = "renesas_usbhs",
+ .id = 0,
+ .dev = {
+ .platform_data = &usbhs0_private.info,
+ },
+ .num_resources = ARRAY_SIZE(usbhs0_resources),
+ .resource = usbhs0_resources,
+};
+
+/* USBHS1 is connected to CN31 which takes a USB Mini-AB plug
+ *
+ * Use J30 to select between Host and Function. This setting
+ * can however not be detected by software. Hotplug of USBHS1
+ * is provided via IRQ8.
+ */
+#define IRQ8 evt2irq(0x0300)
+
+/* USBHS1 USB Host support via r8a66597_hcd */
static void usb1_host_port_power(int port, int power)
{
if (!power) /* only power-on is supported for now */
@@ -579,9 +693,9 @@ static struct r8a66597_platdata usb1_host_data = {
static struct resource usb1_host_resources[] = {
[0] = {
- .name = "USBHS",
- .start = 0xE68B0000,
- .end = 0xE68B00E6 - 1,
+ .name = "USBHS1",
+ .start = 0xe68b0000,
+ .end = 0xe68b00e6 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -602,37 +716,14 @@ static struct platform_device usb1_host_device = {
.resource = usb1_host_resources,
};
-/* USB1 (Function) */
+/* USBHS1 USB Function support via renesas_usbhs */
+
#define USB_PHY_MODE (1 << 4)
#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
#define USB_PHY_ON (1 << 1)
#define USB_PHY_OFF (1 << 0)
#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
-struct usbhs_private {
- unsigned int irq;
- unsigned int usbphyaddr;
- unsigned int usbcrcaddr;
- struct renesas_usbhs_platform_info info;
-};
-
-#define usbhs_get_priv(pdev) \
- container_of(renesas_usbhs_get_info(pdev), \
- struct usbhs_private, info)
-
-#define usbhs_is_connected(priv) \
- (!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
-
-static int usbhs1_get_id(struct platform_device *pdev)
-{
- return USBHS_GADGET;
-}
-
-static int usbhs1_get_vbus(struct platform_device *pdev)
-{
- return usbhs_is_connected(usbhs_get_priv(pdev));
-}
-
static irqreturn_t usbhs1_interrupt(int irq, void *data)
{
struct platform_device *pdev = data;
@@ -654,12 +745,10 @@ static int usbhs1_hardware_init(struct platform_device *pdev)
struct usbhs_private *priv = usbhs_get_priv(pdev);
int ret;
- irq_set_irq_type(priv->irq, IRQ_TYPE_LEVEL_HIGH);
-
/* clear interrupt status */
__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
- ret = request_irq(priv->irq, usbhs1_interrupt, 0,
+ ret = request_irq(IRQ8, usbhs1_interrupt, IRQF_TRIGGER_HIGH,
dev_name(&pdev->dev), pdev);
if (ret) {
dev_err(&pdev->dev, "request_irq err\n");
@@ -679,15 +768,12 @@ static void usbhs1_hardware_exit(struct platform_device *pdev)
/* clear interrupt status */
__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
- free_irq(priv->irq, pdev);
+ free_irq(IRQ8, pdev);
}
-static void usbhs1_phy_reset(struct platform_device *pdev)
+static int usbhs1_get_id(struct platform_device *pdev)
{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
-
- /* init phy */
- __raw_writew(0x8a0a, priv->usbcrcaddr);
+ return USBHS_GADGET;
}
static u32 usbhs1_pipe_cfg[] = {
@@ -710,16 +796,15 @@ static u32 usbhs1_pipe_cfg[] = {
};
static struct usbhs_private usbhs1_private = {
- .irq = evt2irq(0x0300), /* IRQ8 */
- .usbphyaddr = 0xE60581E2, /* USBPHY1INTAP */
- .usbcrcaddr = 0xE6058130, /* USBCR4 */
+ .usbphyaddr = 0xe60581e2, /* USBPHY1INTAP */
+ .usbcrcaddr = 0xe6058130, /* USBCR4 */
.info = {
.platform_callback = {
.hardware_init = usbhs1_hardware_init,
.hardware_exit = usbhs1_hardware_exit,
- .phy_reset = usbhs1_phy_reset,
.get_id = usbhs1_get_id,
- .get_vbus = usbhs1_get_vbus,
+ .phy_reset = usbhs_phy_reset,
+ .get_vbus = usbhs_get_vbus,
},
.driver_param = {
.buswait_bwait = 4,
@@ -731,9 +816,9 @@ static struct usbhs_private usbhs1_private = {
static struct resource usbhs1_resources[] = {
[0] = {
- .name = "USBHS",
- .start = 0xE68B0000,
- .end = 0xE68B00E6 - 1,
+ .name = "USBHS1",
+ .start = 0xe68b0000,
+ .end = 0xe68b00e6 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -752,7 +837,6 @@ static struct platform_device usbhs1_device = {
.resource = usbhs1_resources,
};
-
/* LED */
static struct gpio_led mackerel_leds[] = {
{
@@ -1203,6 +1287,7 @@ static struct platform_device *mackerel_devices[] __initdata = {
&nor_flash_device,
&smc911x_device,
&lcdc_device,
+ &usbhs0_device,
&usb1_host_device,
&usbhs1_device,
&leds_device,
@@ -1301,6 +1386,7 @@ static void __init mackerel_map_io(void)
#define GPIO_PORT9CR 0xE6051009
#define GPIO_PORT10CR 0xE605100A
+#define GPIO_PORT167CR 0xE60520A7
#define GPIO_PORT168CR 0xE60520A8
#define SRCR4 0xe61580bc
#define USCCR1 0xE6058144
@@ -1354,17 +1440,17 @@ static void __init mackerel_init(void)
gpio_request(GPIO_PORT151, NULL); /* LCDDON */
gpio_direction_output(GPIO_PORT151, 1);
- /* USB enable */
- gpio_request(GPIO_FN_VBUS0_1, NULL);
- gpio_request(GPIO_FN_IDIN_1_18, NULL);
- gpio_request(GPIO_FN_PWEN_1_115, NULL);
- gpio_request(GPIO_FN_OVCN_1_114, NULL);
- gpio_request(GPIO_FN_EXTLP_1, NULL);
- gpio_request(GPIO_FN_OVCN2_1, NULL);
- gpio_pull_down(GPIO_PORT168CR);
-
- /* setup USB phy */
- __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
+ /* USBHS0 */
+ gpio_request(GPIO_FN_VBUS0_0, NULL);
+ gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
+
+ /* USBHS1 */
+ gpio_request(GPIO_FN_VBUS0_1, NULL);
+ gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
+ gpio_request(GPIO_FN_IDIN_1_113, NULL);
+
+ /* USB phy tweak to make the r8a66597_hcd host driver work */
+ __raw_writew(0x8a0a, 0xe6058130); /* USBCR4 */
/* enable FSI2 port A (ak4643) */
gpio_request(GPIO_FN_FSIAIBT, NULL);
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 5d0e150..a911a60 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -250,6 +250,11 @@ static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
+{
+ return 0; /* always allow wakeup */
+}
+
void __init sh73a0_init_irq(void)
{
void __iomem *gic_dist_base = __io(0xf0001000);
@@ -257,6 +262,7 @@ void __init sh73a0_init_irq(void)
void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
gic_init(0, 29, gic_dist_base, gic_cpu_base);
+ gic_arch_extn.irq_set_wake = sh73a0_set_wake;
register_intc_controller(&intcs_desc);
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index 2c10190..e546017 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -38,7 +38,7 @@ static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFA,
.irqs = { evt2irq(0xc00), evt2irq(0xc00),
evt2irq(0xc00), evt2irq(0xc00) },
};
@@ -57,7 +57,7 @@ static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFA,
.irqs = { evt2irq(0xc20), evt2irq(0xc20),
evt2irq(0xc20), evt2irq(0xc20) },
};
@@ -76,7 +76,7 @@ static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFA,
.irqs = { evt2irq(0xc40), evt2irq(0xc40),
evt2irq(0xc40), evt2irq(0xc40) },
};
@@ -95,7 +95,7 @@ static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFA,
.irqs = { evt2irq(0xc60), evt2irq(0xc60),
evt2irq(0xc60), evt2irq(0xc60) },
};
@@ -114,7 +114,7 @@ static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFA,
.irqs = { evt2irq(0xd20), evt2irq(0xd20),
evt2irq(0xd20), evt2irq(0xd20) },
};
@@ -133,7 +133,7 @@ static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFA,
.irqs = { evt2irq(0xd40), evt2irq(0xd40),
evt2irq(0xd40), evt2irq(0xd40) },
};
@@ -152,7 +152,7 @@ static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4,
- .type = PORT_SCIF,
+ .type = PORT_SCIFB,
.irqs = { evt2irq(0xd60), evt2irq(0xd60),
evt2irq(0xd60), evt2irq(0xd60) },
};
diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h
index c34f3ea..4f50ca8 100644
--- a/arch/arm/mach-u300/clock.h
+++ b/arch/arm/mach-u300/clock.h
@@ -31,7 +31,7 @@ struct clk {
bool reset;
__u16 clk_val;
__s8 usecount;
- __u32 res_reg;
+ void __iomem * res_reg;
__u16 res_mask;
bool hw_ctrld;
diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h
index 8b85df4..035fdc9 100644
--- a/arch/arm/mach-u300/include/mach/u300-regs.h
+++ b/arch/arm/mach-u300/include/mach/u300-regs.h
@@ -18,6 +18,12 @@
* the defines are used for setting up the I/O memory mapping.
*/
+#ifdef __ASSEMBLER__
+#define IOMEM(a) (a)
+#else
+#define IOMEM(a) (void __iomem *) a
+#endif
+
/* NAND Flash CS0 */
#define U300_NAND_CS0_PHYS_BASE 0x80000000
@@ -48,13 +54,6 @@
#endif
/*
- * All the following peripherals are specified at their PHYSICAL address,
- * so if you need to access them (in the kernel), you MUST use the macros
- * defined in <asm/io.h> to map to the IO_ADDRESS_AHB() IO_ADDRESS_FAST()
- * etc.
- */
-
-/*
* AHB peripherals
*/
@@ -63,11 +62,11 @@
/* Vectored Interrupt Controller 0, servicing 32 interrupts */
#define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000)
-#define U300_INTCON0_VBASE (U300_AHB_PER_VIRT_BASE+0x1000)
+#define U300_INTCON0_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
/* Vectored Interrupt Controller 1, servicing 32 interrupts */
#define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000)
-#define U300_INTCON1_VBASE (U300_AHB_PER_VIRT_BASE+0x2000)
+#define U300_INTCON1_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
/* Memory Stick Pro (MSPRO) controller */
#define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000)
@@ -115,7 +114,7 @@
/* SYSCON */
#define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000)
-#define U300_SYSCON_VBASE (U300_SLOW_PER_VIRT_BASE+0x1000)
+#define U300_SYSCON_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
/* Watchdog */
#define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000)
@@ -125,7 +124,7 @@
/* APP side special timer */
#define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000)
-#define U300_TIMER_APP_VBASE (U300_SLOW_PER_VIRT_BASE+0x4000)
+#define U300_TIMER_APP_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
/* Keypad */
#define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000)
@@ -181,5 +180,4 @@
* Virtual accessor macros for static devices
*/
-
#endif
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index 891cf44..18d7fa0 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -411,8 +411,7 @@ static void __init u300_timer_init(void)
/* Use general purpose timer 2 as clock source */
if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC,
"GPT2", rate, 300, 32, clocksource_mmio_readl_up))
- printk(KERN_ERR "timer: failed to initialize clock "
- "source %s\n", clocksource_u300_1mhz.name);
+ pr_err("timer: failed to initialize U300 clock source\n");
clockevents_calc_mult_shift(&clockevent_u300_1mhz,
rate, APPTIMER_MIN_RANGE);
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 285edcd..9e6b93b 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -46,12 +46,6 @@ static struct map_desc v2m_io_desc[] __initdata = {
},
};
-static void __init v2m_init_early(void)
-{
- ct_desc->init_early();
- versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
-}
-
static void __init v2m_timer_init(void)
{
u32 scctrl;
@@ -365,6 +359,13 @@ static struct clk_lookup v2m_lookups[] = {
},
};
+static void __init v2m_init_early(void)
+{
+ ct_desc->init_early();
+ clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
+ versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
+}
+
static void v2m_power_off(void)
{
if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
@@ -418,8 +419,6 @@ static void __init v2m_init(void)
{
int i;
- clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
-
platform_device_register(&v2m_pcie_i2c_device);
platform_device_register(&v2m_ddc_i2c_device);
platform_device_register(&v2m_flash_device);
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 8bfae96..131f381 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -24,7 +24,9 @@ DEFINE_PER_CPU(struct mm_struct *, current_mm);
/*
* We fork()ed a process, and we need a new context for the child
- * to run in.
+ * to run in. We reserve version 0 for initial tasks so we will
+ * always allocate an ASID. The ASID 0 is reserved for the TTBR
+ * register changing sequence.
*/
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
@@ -34,11 +36,8 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
static void flush_context(void)
{
- u32 ttb;
- /* Copy TTBR1 into TTBR0 */
- asm volatile("mrc p15, 0, %0, c2, c0, 1\n"
- "mcr p15, 0, %0, c2, c0, 0"
- : "=r" (ttb));
+ /* set the reserved ASID before flushing the TLB */
+ asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (0));
isb();
local_flush_tlb_all();
if (icache_is_vivt_asid_tagged()) {
@@ -94,14 +93,13 @@ static void reset_context(void *info)
return;
smp_rmb();
- asid = cpu_last_asid + cpu;
+ asid = cpu_last_asid + cpu + 1;
flush_context();
set_mm_context(mm, asid);
/* set the new ASID */
- asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id));
- isb();
+ cpu_switch_mm(mm->pgd, mm);
}
#else
@@ -144,13 +142,13 @@ void __new_context(struct mm_struct *mm)
* to start a new version and flush the TLB.
*/
if (unlikely((asid & ~ASID_MASK) == 0)) {
- asid = cpu_last_asid + smp_processor_id();
+ asid = cpu_last_asid + smp_processor_id() + 1;
flush_context();
#ifdef CONFIG_SMP
smp_wmb();
smp_call_function(reset_context, NULL, 1);
#endif
- cpu_last_asid += NR_CPUS - 1;
+ cpu_last_asid += NR_CPUS;
}
set_mm_context(mm, asid);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 2c2cce9..c19571c 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -331,6 +331,12 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (phys_initrd_size &&
+ !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
+ pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
+ phys_initrd_start, phys_initrd_size);
+ phys_initrd_start = phys_initrd_size = 0;
+ }
+ if (phys_initrd_size &&
memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
phys_initrd_start, phys_initrd_size);
@@ -635,7 +641,8 @@ void __init mem_init(void)
" modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
" .init : 0x%p" " - 0x%p" " (%4d kB)\n"
" .text : 0x%p" " - 0x%p" " (%4d kB)\n"
- " .data : 0x%p" " - 0x%p" " (%4d kB)\n",
+ " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .bss : 0x%p" " - 0x%p" " (%4d kB)\n",
MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
(PAGE_SIZE)),
@@ -657,7 +664,8 @@ void __init mem_init(void)
MLK_ROUNDUP(__init_begin, __init_end),
MLK_ROUNDUP(_text, _etext),
- MLK_ROUNDUP(_sdata, _edata));
+ MLK_ROUNDUP(_sdata, _edata),
+ MLK_ROUNDUP(__bss_start, __bss_stop));
#undef MLK
#undef MLM
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index e4c165c..537ffcb 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -146,7 +146,7 @@ __arm7tdmi_proc_info:
.long 0
.long 0
.long v4_cache_fns
- .size __arm7tdmi_proc_info, . - __arm7dmi_proc_info
+ .size __arm7tdmi_proc_info, . - __arm7tdmi_proc_info
.type __triscenda7_proc_info, #object
__triscenda7_proc_info:
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index 7b7ebd4..546b54d 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -116,7 +116,7 @@ __arm9tdmi_proc_info:
.long 0
.long 0
.long v4_cache_fns
- .size __arm9tdmi_proc_info, . - __arm9dmi_proc_info
+ .size __arm9tdmi_proc_info, . - __arm9tdmi_proc_info
.type __p2001_proc_info, #object
__p2001_proc_info:
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index b3b566e..3c38678 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -108,16 +108,18 @@ ENTRY(cpu_v7_switch_mm)
#ifdef CONFIG_ARM_ERRATA_430973
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
#endif
- mrc p15, 0, r2, c2, c0, 1 @ load TTB 1
- mcr p15, 0, r2, c2, c0, 0 @ into TTB 0
+#ifdef CONFIG_ARM_ERRATA_754322
+ dsb
+#endif
+ mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
+ isb
+1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
isb
#ifdef CONFIG_ARM_ERRATA_754322
dsb
#endif
mcr p15, 0, r1, c13, c0, 1 @ set context ID
isb
- mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
- isb
#endif
mov pc, lr
ENDPROC(cpu_v7_switch_mm)
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c
index 3538b85..b130f60 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-dma.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c
@@ -139,7 +139,7 @@ static struct sdma_script_start_addrs addr_imx35_to2 = {
#endif
#ifdef CONFIG_SOC_IMX51
-static struct sdma_script_start_addrs addr_imx51_to1 = {
+static struct sdma_script_start_addrs addr_imx51 = {
.ap_2_ap_addr = 642,
.uart_2_mcu_addr = 817,
.mcu_2_app_addr = 747,
@@ -196,7 +196,9 @@ static int __init imxXX_add_imx_dma(void)
#if defined(CONFIG_SOC_IMX51)
if (cpu_is_mx51()) {
- imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51_to1;
+ int to_version = mx51_revision() >> 4;
+ imx51_imx_sdma_data.pdata.to_version = to_version;
+ imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51;
ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
} else
#endif
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index ac25b91..9e2cd5a 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -232,7 +232,7 @@ config OMAP_CARVEOUT_MEMPOOL_SIZE
choice
prompt "OMAP PM layer selection"
depends on ARCH_OMAP
- default OMAP_PM_NOOP
+ default OMAP_PM
config OMAP_PM_NONE
bool "No PM layer"
@@ -240,6 +240,9 @@ config OMAP_PM_NONE
config OMAP_PM_NOOP
bool "No-op/debug PM layer"
+config OMAP_PM
+ depends on PM
+ bool "OMAP PM layer implementation"
endchoice
endmenu
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 69c1966..f3ab483 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_OMAP_RPMSG) += omap_rpmsg.o
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
@@ -32,4 +31,5 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
# OMAP mailbox framework
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
-obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-interface.o
+obj-$(CONFIG_OMAP_PM) += omap-pm-interface.o omap-pm-helper.o
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 6922f3b..e81f9a7 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -16,19 +16,25 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/memblock.h>
+#include <linux/err.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mmc.h>
#include <mach/gpio.h>
#include <plat/menelaus.h>
#include <plat/mcbsp.h>
+#include <plat/mcpdm.h>
#include <plat/omap44xx.h>
+#include <sound/omap-abe-dsp.h>
+
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
@@ -77,31 +83,38 @@ void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
-static struct resource mcpdm_resources[] = {
+static struct omap_device_pm_latency omap_mcpdm_latency[] = {
{
- .name = "mcpdm_mem",
- .start = OMAP44XX_MCPDM_BASE,
- .end = OMAP44XX_MCPDM_BASE + SZ_4K,
- .flags = IORESOURCE_MEM,
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
},
- {
- .name = "mcpdm_irq",
- .start = OMAP44XX_IRQ_MCPDM,
- .end = OMAP44XX_IRQ_MCPDM,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device omap_mcpdm_device = {
- .name = "omap-mcpdm",
- .id = -1,
- .num_resources = ARRAY_SIZE(mcpdm_resources),
- .resource = mcpdm_resources,
};
static void omap_init_mcpdm(void)
{
- (void) platform_device_register(&omap_mcpdm_device);
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ struct omap_mcpdm_platform_data *pdata;
+
+ oh = omap_hwmod_lookup("mcpdm");
+ if (!oh) {
+ printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
+ return;
+ }
+
+ pdata = kzalloc(sizeof(struct omap_mcpdm_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ printk(KERN_ERR "Could not allocate platform data\n");
+ return;
+ }
+
+ od = omap_device_build("omap-mcpdm", -1, oh, pdata,
+ sizeof(struct omap_mcpdm_platform_data),
+ omap_mcpdm_latency,
+ ARRAY_SIZE(omap_mcpdm_latency), 0);
+ if (IS_ERR(od))
+ printk(KERN_ERR "Could not build omap_device for omap-mcpdm-dai\n");
}
#else
static inline void omap_init_mcpdm(void) {}
@@ -159,6 +172,55 @@ fail:
/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP) || \
+ defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
+
+static struct omap_device_pm_latency omap_aess_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void omap_init_aess(void)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ struct omap4_abe_dsp_pdata *pdata;
+
+ oh = omap_hwmod_lookup("aess");
+ if (!oh) {
+ printk (KERN_ERR "Could not look up aess hw_mod\n");
+ return;
+ }
+
+ pdata = kzalloc(sizeof(struct omap4_abe_dsp_pdata), GFP_KERNEL);
+ if (!pdata) {
+ printk(KERN_ERR "Could not allocate platform data\n");
+ return;
+ }
+
+ /* FIXME: Add correct context loss counter */
+ //pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
+ od = omap_device_build("aess", -1, oh, pdata,
+ sizeof(struct omap4_abe_dsp_pdata),
+ omap_aess_latency,
+ ARRAY_SIZE(omap_aess_latency), 0);
+
+ kfree(pdata);
+
+ if (IS_ERR(od))
+ printk(KERN_ERR "Could not build omap_device for omap-aess-audio\n");
+}
+#else
+static inline void omap_init_aess(void) {}
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
#ifdef CONFIG_ARCH_OMAP2
@@ -190,8 +252,6 @@ static void omap_init_rng(void)
static inline void omap_init_rng(void) {}
#endif
-/*-------------------------------------------------------------------------*/
-
/* Numbering for the SPI-capable controllers when used for SPI:
* spi = 1
* uwire = 2
@@ -302,6 +362,7 @@ static int __init omap_init_devices(void)
*/
omap_init_rng();
omap_init_mcpdm();
+ omap_init_aess();
omap_init_uwire();
return 0;
}
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 3341ca4..f8dc82f 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -113,16 +113,6 @@ static inline int omap1_i2c_add_bus(int bus_id)
#ifdef CONFIG_ARCH_OMAP2PLUS
-/*
- * XXX This function is a temporary compatibility wrapper - only
- * needed until the I2C driver can be converted to call
- * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
- */
-static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
-{
- omap_pm_set_max_mpu_wakeup_lat(dev, t);
-}
-
static struct omap_device_pm_latency omap_i2c_latency[] = {
[0] = {
.deactivate_func = omap_device_idle_hwmods,
@@ -158,8 +148,8 @@ static inline int omap2_i2c_add_bus(int bus_id)
* completes.
* Only omap3 has support for constraints
*/
- if (cpu_is_omap34xx())
- pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+ if (cpu_is_omap34xx() || cpu_is_omap44xx())
+ pdata->needs_wakeup_latency = true;
od = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index f1899a3..324446b 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -39,11 +39,13 @@ struct omap_clk {
#define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */
#define CK_443X (1 << 11)
#define CK_TI816X (1 << 12)
+#define CK_446X (1 << 13)
#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
+#define CK_44XX (CK_443X | CK_446X)
#endif
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 006e599..12a9ced 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -56,12 +56,14 @@ struct clkops {
#define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */
#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */
#define RATE_IN_36XX (1 << 4)
-#define RATE_IN_4430 (1 << 5)
+#define RATE_IN_443X (1 << 5)
#define RATE_IN_TI816X (1 << 6)
+#define RATE_IN_446X (1 << 7)
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX)
+#define RATE_IN_44XX (RATE_IN_443X | RATE_IN_446X)
/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX)
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 5288130..b2c2247 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -53,6 +53,7 @@ struct omap_globals {
unsigned long sms; /* SDRAM Memory Scheduler */
unsigned long ctrl; /* System Control Module */
unsigned long ctrl_pad; /* PAD Control Module */
+ unsigned long ctrl_wk_pad; /* PAD Control WakeUp Module */
unsigned long prm; /* Power and Reset Management */
unsigned long cm; /* Clock Management */
unsigned long cm2;
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 8198bb6..3faa251 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -88,6 +88,7 @@ unsigned int omap_rev(void);
* cpu_is_omap243x(): True for OMAP2430
* cpu_is_omap343x(): True for OMAP3430
* cpu_is_omap443x(): True for OMAP4430
+ * cpu_is_omap446x(): True for OMAP4460
*/
#define GET_OMAP_CLASS (omap_rev() & 0xff)
@@ -123,6 +124,7 @@ IS_OMAP_SUBCLASS(243x, 0x243)
IS_OMAP_SUBCLASS(343x, 0x343)
IS_OMAP_SUBCLASS(363x, 0x363)
IS_OMAP_SUBCLASS(443x, 0x443)
+IS_OMAP_SUBCLASS(446x, 0x446)
IS_TI_SUBCLASS(816x, 0x816)
@@ -137,6 +139,7 @@ IS_TI_SUBCLASS(816x, 0x816)
#define cpu_is_ti816x() 0
#define cpu_is_omap44xx() 0
#define cpu_is_omap443x() 0
+#define cpu_is_omap446x() 0
#if defined(MULTI_OMAP1)
# if defined(CONFIG_ARCH_OMAP730)
@@ -361,8 +364,10 @@ IS_OMAP_TYPE(3517, 0x3517)
# if defined(CONFIG_ARCH_OMAP4)
# undef cpu_is_omap44xx
# undef cpu_is_omap443x
+# undef cpu_is_omap446x
# define cpu_is_omap44xx() is_omap44xx()
# define cpu_is_omap443x() is_omap443x()
+# define cpu_is_omap446x() is_omap446x()
# endif
/* Macros to detect if we have OMAP1 or OMAP2 */
@@ -410,6 +415,9 @@ IS_OMAP_TYPE(3517, 0x3517)
#define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8))
#define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8))
+#define OMAP446X_CLASS 0x44600044
+#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8))
+
/*
* omap_chip bits
*
@@ -439,14 +447,19 @@ IS_OMAP_TYPE(3517, 0x3517)
#define CHIP_IS_OMAP4430ES2_1 (1 << 12)
#define CHIP_IS_OMAP4430ES2_2 (1 << 13)
#define CHIP_IS_TI816X (1 << 14)
+#define CHIP_IS_OMAP4460ES1_0 (1 << 15)
#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
-#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \
+#define CHIP_IS_OMAP443X (CHIP_IS_OMAP4430ES1 | \
CHIP_IS_OMAP4430ES2 | \
CHIP_IS_OMAP4430ES2_1 | \
CHIP_IS_OMAP4430ES2_2)
+#define CHIP_IS_OMAP446X CHIP_IS_OMAP4460ES1_0
+
+#define CHIP_IS_OMAP44XX (CHIP_IS_OMAP443X | CHIP_IS_OMAP446X)
+
/*
* "GE" here represents "greater than or equal to" in terms of ES
* levels. So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
diff --git a/arch/arm/plat-omap/include/plat/dsscomp.h b/arch/arm/plat-omap/include/plat/dsscomp.h
new file mode 100644
index 0000000..acafe0f
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dsscomp.h
@@ -0,0 +1,23 @@
+#ifndef _ARCH_ARM_PLAT_OMAP_DSSCOMP_H
+#define _ARCH_ARM_PLAT_OMAP_DSSCOMP_H
+
+#include <video/omapdss.h>
+
+/* queuing operations */
+typedef struct dsscomp_data *dsscomp_t; /* handle */
+
+dsscomp_t dsscomp_new_sync_id(struct omap_overlay_manager *mgr, u32 sync_id);
+u32 dsscomp_first_sync_id(struct omap_overlay_manager *mgr);
+dsscomp_t dsscomp_find(struct omap_overlay_manager *mgr, u32 sync_id);
+u32 dsscomp_get_ovls(dsscomp_t comp);
+int dsscomp_set_ovl(dsscomp_t comp, struct dss2_ovl_info *ovl);
+int dsscomp_get_ovl(dsscomp_t comp, u32 ix, struct dss2_ovl_info *ovl);
+int dsscomp_set_mgr(dsscomp_t comp, struct dss2_mgr_info *mgr);
+int dsscomp_get_mgr(dsscomp_t comp, struct dss2_mgr_info *mgr);
+int dsscomp_setup(dsscomp_t comp, enum dsscomp_setup_mode mode,
+ struct dss2_rect_t win);
+int dsscomp_apply(dsscomp_t comp);
+int dsscomp_wait(dsscomp_t comp, enum dsscomp_wait_phase phase, int timeout);
+void dsscomp_drop(dsscomp_t c);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpu.h b/arch/arm/plat-omap/include/plat/gpu.h
new file mode 100644
index 0000000..70dcc92
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpu.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/plat-omap/include/plat/gpu.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef OMAP_GPU_H
+#define OMAP_GPU_H
+
+#include <plat/omap-pm.h>
+#include <linux/platform_device.h>
+
+struct gpu_platform_data {
+ void (*set_min_bus_tput)(struct device *dev, u8 agent_id,
+ unsigned long r);
+ int (*device_enable) (struct platform_device *pdev);
+ int (*device_shutdown) (struct platform_device *pdev);
+ int (*device_idle) (struct platform_device *pdev);
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 5a25098..2cfba51 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -407,11 +407,19 @@
#endif
#define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
+#define TWL6040_CODEC_IRQ_BASE TWL6030_IRQ_END
+#ifdef CONFIG_TWL6040_CODEC
+#define TWL6040_CODEC_NR_IRQS 6
+#else
+#define TWL6040_CODEC_NR_IRQS 0
+#endif
+#define TWL6040_CODEC_IRQ_END (TWL6040_CODEC_IRQ_BASE + TWL6040_CODEC_NR_IRQS)
+
/* Total number of interrupts depends on the enabled blocks above */
-#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
+#if (TWL4030_GPIO_IRQ_END > TWL6040_CODEC_IRQ_END)
#define TWL_IRQ_END TWL4030_GPIO_IRQ_END
#else
-#define TWL_IRQ_END TWL6030_IRQ_END
+#define TWL_IRQ_END TWL6040_CODEC_IRQ_END
#endif
/* GPMC related */
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index f8f690a..ddada0b 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -403,6 +403,8 @@ struct omap_mcbsp_platform_data {
#endif
u16 buffer_size;
unsigned int mcbsp_config_type;
+ char clks_pad_src[30];
+ char clks_prcm_src[30];
};
struct omap_mcbsp_st_data {
@@ -448,6 +450,8 @@ struct omap_mcbsp {
struct clk *fclk;
#ifdef CONFIG_ARCH_OMAP3
struct omap_mcbsp_st_data *st_data;
+#endif
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
int dma_op_mode;
u16 max_tx_thres;
u16 max_rx_thres;
@@ -474,7 +478,7 @@ int omap_mcbsp_init(void);
void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
struct omap_mcbsp_platform_data *config, int size);
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
diff --git a/arch/arm/plat-omap/include/plat/mcpdm.h b/arch/arm/plat-omap/include/plat/mcpdm.h
new file mode 100644
index 0000000..1ed2b8f
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/mcpdm.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP_PLAT_MCPDM_H__
+#define __OMAP_PLAT_MCPDM_H__
+
+#include <linux/platform_device.h>
+
+struct omap_mcpdm_platform_data {
+ int (*device_enable) (struct platform_device *pdev);
+ int (*device_shutdown) (struct platform_device *pdev);
+ int (*device_idle) (struct platform_device *pdev);
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index c7b8741..f24ed41 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -108,8 +108,9 @@ struct omap_mmc_platform_data {
unsigned vcc_aux_disable_is_sleep:1;
/* we can put the features above into this variable */
-#define HSMMC_HAS_PBIAS (1 << 0)
-#define HSMMC_HAS_UPDATED_RESET (1 << 1)
+#define HSMMC_HAS_PBIAS (1 << 0)
+#define HSMMC_HAS_UPDATED_RESET (1 << 1)
+#define HSMMC_HAS_48MHZ_MASTER_CLK (1 << 2)
unsigned features;
int switch_pin; /* gpio (card detect) */
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index c0a7520..1bfdf63 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -17,7 +17,9 @@
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
+#include <linux/pm_qos_params.h>
#include <linux/opp.h>
+#include <linux/pm_qos_params.h>
/*
* agent_id values for use with omap_pm_set_min_bus_tput():
@@ -73,7 +75,8 @@ void omap_pm_if_exit(void);
/**
* omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
- * @dev: struct device * requesting the constraint
+ * @qos_request: handle for the constraint. The pointer should be
+ * initialized to NULL
* @t: maximum MPU wakeup latency in microseconds
*
* Request that the maximum interrupt latency for the MPU to be no
@@ -105,7 +108,8 @@ void omap_pm_if_exit(void);
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
* is not satisfiable, or 0 upon success.
*/
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+int omap_pm_set_max_mpu_wakeup_lat(struct pm_qos_request_list **qos_request,
+ long t);
/**
@@ -132,12 +136,12 @@ int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
*
* Multiple calls to omap_pm_set_min_bus_tput() will replace the
* previous rate value for this device. To remove the interconnect
- * throughput restriction for this device, call with r = 0.
+ * throughput restriction for this device, call with r = -1.
*
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
* is not satisfiable, or 0 upon success.
*/
-int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, long r);
/**
@@ -172,7 +176,8 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
/**
* omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
+ * @qos_request: handle for the constraint. The pointer should be
+ * initialized to NULL
* @t: maximum DMA transfer start latency in microseconds
*
* Request that the maximum system DMA transfer start latency for this
@@ -197,7 +202,8 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
* is not satisfiable, or 0 upon success.
*/
-int omap_pm_set_max_sdma_lat(struct device *dev, long t);
+int omap_pm_set_max_sdma_lat(struct pm_qos_request_list **qos_request,
+ long t);
/**
@@ -350,9 +356,18 @@ unsigned long omap_pm_cpu_get_freq(void);
* driver must restore device context. If the number of context losses
* exceeds the maximum positive integer, the function will wrap to 0 and
* continue counting. Returns the number of context losses for this device,
- * or zero upon error.
+ * or -EINVAL upon error.
+ */
+int omap_pm_get_dev_context_loss_count(struct device *dev);
+
+
+/**
+ * omap_pm_set_min_mpu_freq - sets the min frequency the mpu should be allowed
+ * to run. The function works with a granularity of 1000000. Any frequency requested,
+ * will set the mpu frequency to the closet higher frequency that can match the request.
+ * to release the constraint, the f parameter should be passed as -1.
*/
-u32 omap_pm_get_dev_context_loss_count(struct device *dev);
+int omap_pm_set_min_mpu_freq(struct device *dev, unsigned long f);
void omap_pm_enable_off_mode(void);
void omap_pm_disable_off_mode(void);
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 2682043..71e238e 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -112,5 +112,6 @@ struct uart_omap_port {
char name[20];
unsigned long port_activity;
};
+int omap_uart_active(int num, u32 timeout);
#endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index ea2b8a6..c6d131d 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -34,6 +34,7 @@
#define OMAP44XX_GPMC_BASE 0x50000000
#define OMAP443X_SCM_BASE 0x4a002000
#define OMAP443X_CTRL_BASE 0x4a100000
+#define OMAP443X_CTRL_WK_BASE 0x4a31e000
#define OMAP44XX_IC_BASE 0x48200000
#define OMAP44XX_IVA_INTC_BASE 0x40000000
#define IRQ_SIR_IRQ 0x0040
@@ -45,6 +46,7 @@
#define OMAP44XX_WKUPGEN_BASE 0x48281000
#define OMAP44XX_MCPDM_BASE 0x40132000
#define OMAP44XX_MCPDM_L3_BASE 0x49032000
+#define OMAP44XX_SAR_RAM_BASE 0x4a326000
#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)
#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349f..70d31d0 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -107,7 +107,7 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
-u32 omap_device_get_context_loss_count(struct platform_device *pdev);
+int omap_device_get_context_loss_count(struct platform_device *pdev);
/* Other */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1adea9c..a74663a 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -519,8 +519,6 @@ struct omap_hwmod {
const char *main_clk;
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
- char *vdd_name;
- struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr;
@@ -598,7 +596,7 @@ int omap_hwmod_for_each_by_class(const char *classname,
void *user);
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
-u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
+int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
diff --git a/arch/arm/plat-omap/include/plat/rpres.h b/arch/arm/plat-omap/include/plat/rpres.h
new file mode 100644
index 0000000..c80514b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/rpres.h
@@ -0,0 +1,49 @@
+/*
+ * Remote processor resources
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
+
+#ifndef _PLAT_OMAP_RPRES_H
+#define _PLAT_OMAP_RPRES_H
+
+enum {
+ RPRES_INACTIVE,
+ RPRES_ACTIVE,
+};
+
+struct rpres_ops {
+ int (*start)(struct platform_device *pdev);
+ int (*stop)(struct platform_device *pdev);
+ /* no PM for the momment */
+ //int (*set_constraint)(struct device *dev, void *arg);
+ //int (*remove_constraint)(struct device *dev);
+};
+
+struct rpres_platform_data {
+ const char *name;
+ const char *oh_name;
+ struct omap_hwmod *oh;
+ struct rpres_ops *ops;
+ struct clk *opt_clk;
+ const char *opt_clk_name;
+};
+
+struct rpres {
+ struct list_head next;
+ const char *name;
+ struct platform_device *pdev;
+ int state;
+ struct mutex lock;
+};
+
+struct rpres *rpres_get(const char *);
+void rpres_put(struct rpres *);
+#endif /* _PLAT_OMAP_RPRES_H */
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 5587acf..fb5571d 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -75,6 +75,11 @@ static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
{
return __raw_readl(mcbsp->st_data->io_base_st + reg);
}
+
+#define MCBSP_ST_READ(mcbsp, reg) \
+ omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
+#define MCBSP_ST_WRITE(mcbsp, reg, val) \
+ omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
#endif
#define MCBSP_READ(mcbsp, reg) \
@@ -84,11 +89,6 @@ static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
#define MCBSP_READ_CACHE(mcbsp, reg) \
omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
-#define MCBSP_ST_READ(mcbsp, reg) \
- omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
-#define MCBSP_ST_WRITE(mcbsp, reg, val) \
- omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
-
static void omap_mcbsp_dump_reg(u8 id)
{
struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
@@ -292,14 +292,16 @@ int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream)
}
EXPORT_SYMBOL(omap_mcbsp_dma_reg_params);
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
static struct omap_device *find_omap_device_by_dev(struct device *dev)
{
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
return container_of(pdev, struct omap_device, pdev);
}
+#endif
+#ifdef CONFIG_ARCH_OMAP3
static void omap_st_on(struct omap_mcbsp *mcbsp)
{
unsigned int w;
@@ -550,7 +552,12 @@ int omap_st_is_enabled(unsigned int id)
return st_data->enabled;
}
EXPORT_SYMBOL(omap_st_is_enabled);
+#else
+static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
+static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
+#endif
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
/*
* omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
* The threshold parameter is 1 based, and it is converted (threshold - 1)
@@ -754,8 +761,6 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
#else
static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
-static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
-static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
#endif
/*
@@ -1522,7 +1527,7 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
}
EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
#define max_thres(m) (mcbsp->pdata->buffer_size)
#define valid_threshold(m, val) ((val) <= max_thres(m))
#define THRESHOLD_PROP_BUILDER(prop) \
@@ -1613,6 +1618,29 @@ unlock:
static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
+static const struct attribute *additional_attrs[] = {
+ &dev_attr_max_tx_thres.attr,
+ &dev_attr_max_rx_thres.attr,
+ &dev_attr_dma_op_mode.attr,
+ NULL,
+};
+
+static const struct attribute_group additional_attr_group = {
+ .attrs = (struct attribute **)additional_attrs,
+};
+
+static inline int __devinit omap_additional_add(struct device *dev)
+{
+ return sysfs_create_group(&dev->kobj, &additional_attr_group);
+}
+
+static inline void __devexit omap_additional_remove(struct device *dev)
+{
+ sysfs_remove_group(&dev->kobj, &additional_attr_group);
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
static ssize_t st_taps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1671,27 +1699,6 @@ out:
static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
-static const struct attribute *additional_attrs[] = {
- &dev_attr_max_tx_thres.attr,
- &dev_attr_max_rx_thres.attr,
- &dev_attr_dma_op_mode.attr,
- NULL,
-};
-
-static const struct attribute_group additional_attr_group = {
- .attrs = (struct attribute **)additional_attrs,
-};
-
-static inline int __devinit omap_additional_add(struct device *dev)
-{
- return sysfs_create_group(&dev->kobj, &additional_attr_group);
-}
-
-static inline void __devexit omap_additional_remove(struct device *dev)
-{
- sysfs_remove_group(&dev->kobj, &additional_attr_group);
-}
-
static const struct attribute *sidetone_attrs[] = {
&dev_attr_st_taps.attr,
NULL,
@@ -1749,11 +1756,16 @@ static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
kfree(st_data);
}
}
+#else
+static inline int __devinit omap_st_add(struct omap_mcbsp *mcbsp) { return 0; }
+static inline void __devexit omap_st_remove(struct omap_mcbsp *mcbsp) {}
+#endif
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
{
mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
- if (cpu_is_omap34xx()) {
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
/*
* Initially configure the maximum thresholds to a safe value.
* The McBSP FIFO usage with these values should not go under
@@ -1771,26 +1783,26 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
if (omap_additional_add(mcbsp->dev))
dev_warn(mcbsp->dev,
"Unable to create additional controls\n");
+ } else {
+ mcbsp->max_tx_thres = -EINVAL;
+ mcbsp->max_rx_thres = -EINVAL;
+ }
+ if (cpu_is_omap34xx()) {
if (mcbsp->id == 2 || mcbsp->id == 3)
if (omap_st_add(mcbsp))
dev_warn(mcbsp->dev,
"Unable to create sidetone controls\n");
-
- } else {
- mcbsp->max_tx_thres = -EINVAL;
- mcbsp->max_rx_thres = -EINVAL;
}
}
static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
{
- if (cpu_is_omap34xx()) {
+ if (cpu_is_omap34xx() || cpu_is_omap44xx())
omap_additional_remove(mcbsp->dev);
-
+ if (cpu_is_omap34xx())
if (mcbsp->id == 2 || mcbsp->id == 3)
omap_st_remove(mcbsp);
- }
}
#else
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
diff --git a/arch/arm/plat-omap/omap-pm-helper.c b/arch/arm/plat-omap/omap-pm-helper.c
new file mode 100644
index 0000000..0f71c45
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-helper.c
@@ -0,0 +1,321 @@
+/*
+ * omap-pm.c - OMAP power management interface
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Vishwanath BS
+ *
+ * This code is based on plat-omap/omap-pm-noop.c.
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
+ * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+
+/* Interface documentation is in mach/omap-pm.h */
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+#include <plat/common.h>
+#include "../mach-omap2/powerdomain.h"
+#include "omap-pm-helper.h"
+
+struct omap_opp *dsp_opps;
+struct omap_opp *mpu_opps;
+struct omap_opp *l3_opps;
+
+static DEFINE_MUTEX(bus_tput_mutex);
+static DEFINE_MUTEX(mpu_tput_mutex);
+static DEFINE_MUTEX(mpu_lat_mutex);
+
+/* Used to model a Interconnect Throughput */
+static struct interconnect_tput {
+ /* Total no of users at any point of interconnect */
+ u8 no_of_users;
+ /* List of all the current users for interconnect */
+ struct list_head users_list;
+ struct list_head node;
+ /* Protect interconnect throughput */
+ struct mutex throughput_mutex;
+ /* Target level for interconnect throughput */
+ unsigned long target_level;
+
+} *bus_tput;
+
+/* Used to represent a user of a interconnect throughput */
+struct users {
+ /* Device pointer used to uniquely identify the user */
+ struct device *dev;
+ struct list_head node;
+ /* Current level as requested for interconnect throughput by the user */
+ u32 level;
+};
+
+/* Private/Internal Functions */
+
+/**
+ * user_lookup - look up a user by its device pointer, return a pointer
+ * @dev: The device to be looked up
+ *
+ * Looks for a interconnect user by its device pointer. Returns a
+ * pointer to
+ * the struct users if found, else returns NULL.
+ */
+static struct users *user_lookup(struct device *dev)
+{
+ struct users *usr, *tmp_usr;
+
+ usr = NULL;
+ list_for_each_entry(tmp_usr, &bus_tput->users_list, node) {
+ if (tmp_usr->dev == dev) {
+ usr = tmp_usr;
+ break;
+ }
+ }
+
+ return usr;
+}
+
+/**
+ * get_user - gets a new users_list struct dynamically
+ *
+ * This function allocates dynamcially the user node
+ * Returns a pointer to users struct on success. On dynamic allocation
+ * failure
+ * returns a ERR_PTR(-ENOMEM).
+ */
+static struct users *get_user(void)
+{
+ struct users *user;
+
+ user = kmalloc(sizeof(struct users), GFP_KERNEL);
+ if (!user) {
+ pr_err("%s FATAL ERROR: kmalloc failed\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+ return user;
+}
+
+/**
+ * omap_bus_tput_init - Initializes the interconnect throughput
+ * userlist
+ * Allocates memory for global throughput variable dynamically.
+ * Intializes Userlist, no. of users and throughput target level.
+ * Returns 0 on sucess, else returns EINVAL if memory
+ * allocation fails.
+ */
+static int __init omap_bus_tput_init(void)
+{
+ bus_tput = kmalloc(sizeof(struct interconnect_tput), GFP_KERNEL);
+ if (!bus_tput) {
+ pr_err("%s FATAL ERROR: kmalloc failed\n", __func__);
+ return -EINVAL;
+ }
+ INIT_LIST_HEAD(&bus_tput->users_list);
+ mutex_init(&bus_tput->throughput_mutex);
+ bus_tput->no_of_users = 0;
+ bus_tput->target_level = 0;
+ return 0;
+}
+
+/**
+ * add_req_tput - Request for a required level by a device
+ * @dev: Uniquely identifes the caller
+ * @level: The requested level for the interconnect bandwidth in KiB/s
+ *
+ * This function recomputes the target level of the interconnect
+ * bandwidth
+ * based on the level requested by all the users.
+ * Multiple calls to this function by the same device will
+ * replace the previous level requested
+ * Returns the updated level of interconnect throughput.
+ * In case of Invalid dev or user pointer, it returns 0.
+ */
+static unsigned long add_req_tput(struct device *dev, unsigned long level)
+{
+ int ret;
+ struct users *user;
+
+ if (!dev) {
+ pr_err("Invalid dev pointer\n");
+ ret = 0;
+ }
+ mutex_lock(&bus_tput->throughput_mutex);
+ user = user_lookup(dev);
+ if (user == NULL) {
+ user = get_user();
+ if (IS_ERR(user)) {
+ pr_err("Couldn't get user from the list to"
+ "add new throughput constraint");
+ ret = 0;
+ goto unlock;
+ }
+ bus_tput->target_level += level;
+ bus_tput->no_of_users++;
+ user->dev = dev;
+ list_add(&user->node, &bus_tput->users_list);
+ user->level = level;
+ } else {
+ bus_tput->target_level -= user->level;
+ bus_tput->target_level += level;
+ user->level = level;
+ }
+ ret = bus_tput->target_level;
+unlock:
+ mutex_unlock(&bus_tput->throughput_mutex);
+ return ret;
+}
+
+/**
+ * remove_req_tput - Release a previously requested level of
+ * a throughput level for interconnect
+ * @dev: Device pointer to dev
+ *
+ * This function recomputes the target level of the interconnect
+ * throughput after removing
+ * the level requested by the user.
+ * Returns 0, if the dev structure is invalid
+ * else returns modified interconnect throughput rate.
+ */
+static unsigned long remove_req_tput(struct device *dev)
+{
+ struct users *user;
+ int found = 0;
+ int ret;
+
+ mutex_lock(&bus_tput->throughput_mutex);
+ list_for_each_entry(user, &bus_tput->users_list, node) {
+ if (user->dev == dev) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ /* No such user exists */
+ pr_err("Invalid Device Structure\n");
+ ret = 0;
+ goto unlock;
+ }
+ bus_tput->target_level -= user->level;
+ bus_tput->no_of_users--;
+ list_del(&user->node);
+ kfree(user);
+ ret = bus_tput->target_level;
+unlock:
+ mutex_unlock(&bus_tput->throughput_mutex);
+ return ret;
+}
+
+int omap_pm_set_min_bus_tput_helper(struct device *dev, u8 agent_id, long r)
+{
+
+ int ret = 0;
+ struct device *l3_dev;
+
+ /*
+ * TODO: This will go away when complete device scaling support for
+ * L3 is added.
+ */
+#if 0
+ static struct device dummy_l3_dev;
+#endif
+ unsigned long target_level = 0;
+
+ mutex_lock(&bus_tput_mutex);
+
+ l3_dev = omap2_get_l3_device();
+ if (!l3_dev) {
+ pr_err("Unable to get l3 device pointer");
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ if (r == -1)
+ target_level = remove_req_tput(dev);
+ else
+ target_level = add_req_tput(dev, r);
+
+ /* Convert the throughput(in KiB/s) into Hz. */
+ target_level = (target_level * 1000) / 4;
+
+ /*
+ * TODO: This will go away when complete device scaling support for
+ * L3 is added.
+ */
+#if 0
+ ret = omap_device_scale(&dummy_l3_dev, l3_dev, target_level);
+ if (ret)
+ pr_err("Failed: change interconnect bandwidth to %ld\n",
+ target_level);
+#else
+ WARN(1, "OMAP PM: %s: constraint not called, needs DVFS", __func__);
+#endif
+unlock:
+ mutex_unlock(&bus_tput_mutex);
+ return ret;
+}
+
+int omap_pm_set_max_dev_wakeup_lat_helper(struct device *req_dev,
+ struct device *dev, long t)
+{
+ struct omap_device *odev;
+ struct powerdomain *pwrdm_dev;
+ struct platform_device *pdev;
+ int ret = 0;
+
+ if (!req_dev || !dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ /* Look for the devices Power Domain */
+ pdev = container_of(dev, struct platform_device, dev);
+
+ /* Try to catch non platform devices. */
+ if (pdev->name == NULL) {
+ pr_err("OMAP-PM: Error: platform device not valid\n");
+ return -EINVAL;
+ }
+
+ odev = to_omap_device(pdev);
+ if (odev) {
+ pwrdm_dev = omap_device_get_pwrdm(odev);
+ } else {
+ pr_err("OMAP-PM: Error: Could not find omap_device for %s\n",
+ pdev->name);
+ return -EINVAL;
+ }
+
+ /* Catch devices with undefined powerdomains. */
+ if (!pwrdm_dev) {
+ pr_err("OMAP-PM: Error: could not find parent pwrdm for %s\n",
+ pdev->name);
+ return -EINVAL;
+ }
+
+ if (t == -1)
+ ret = pwrdm_wakeuplat_release_constraint(pwrdm_dev, req_dev);
+ else
+ ret = pwrdm_wakeuplat_set_constraint(pwrdm_dev, req_dev, t);
+
+ return ret;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init_helper(void)
+{
+ int ret;
+ ret = omap_bus_tput_init();
+ if (ret)
+ pr_err("Failed: init of interconnect bandwidth users list\n");
+ return ret;
+}
diff --git a/arch/arm/plat-omap/omap-pm-helper.h b/arch/arm/plat-omap/omap-pm-helper.h
new file mode 100644
index 0000000..9c4b5d7
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-helper.h
@@ -0,0 +1,40 @@
+/*
+ * OMAP PM interface helpers
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * 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 __OMAP_PM_HELPER_INTERFACE_H__
+#define __OMAP_PM_HELPER_INTERFACE_H__
+
+#ifdef CONFIG_OMAP_PM
+int omap_pm_set_min_bus_tput_helper(struct device *dev, u8 agent_id, long r);
+int omap_pm_set_max_dev_wakeup_lat_helper(struct device *req_dev,
+ struct device *dev, long t);
+int __init omap_pm_if_init_helper(void);
+
+#else
+static inline int omap_pm_set_min_bus_tput_helper(struct device *dev,
+ u8 agent_id, long r)
+{
+ return 0;
+}
+
+static inline int omap_pm_set_max_dev_wakeup_lat_helper(struct device *req_dev,
+ struct device *dev, long t)
+{
+ return 0;
+}
+
+static inline int omap_pm_if_init_helper(void)
+{
+ return 0;
+}
+#endif /* CONFIG_OMAP_PM */
+
+#endif /* __OMAP_PM_HELPER_INTERFACE_H__ */
diff --git a/arch/arm/plat-omap/omap-pm-interface.c b/arch/arm/plat-omap/omap-pm-interface.c
new file mode 100644
index 0000000..67319a7
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-interface.c
@@ -0,0 +1,239 @@
+/*
+ * omap-pm-interface.c - OMAP power management interface
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge.
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
+ * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+/* Interface documentation is in mach/omap-pm.h */
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+
+#include "omap-pm-helper.h"
+
+static bool off_mode_enabled;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ * WARNING: Device drivers need to now use pm_qos directly.
+ */
+int omap_pm_set_max_mpu_wakeup_lat(struct pm_qos_request_list **pmqos_req,
+ long t)
+{
+ WARN(1, "Deprecated %s: Driver should use pm_qos to add request\n",
+ __func__);
+
+ return -EINVAL;
+}
+
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, long r)
+{
+ int ret;
+ if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+ agent_id != OCP_TARGET_AGENT)) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (r == -1)
+ pr_debug("OMAP PM: remove min bus tput constraint: "
+ "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+ else
+ pr_debug("OMAP PM: add min bus tput constraint: "
+ "dev %s for agent_id %d: rate %ld KiB\n",
+ dev_name(dev), agent_id, r);
+
+ ret = omap_pm_set_min_bus_tput_helper(dev, agent_id, r);
+
+ return ret;
+}
+
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+ long t)
+{
+ int ret;
+ if (!req_dev || !dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (t == -1)
+ pr_debug("OMAP PM: remove max device latency constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add max device latency constraint: "
+ "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+ ret = omap_pm_set_max_dev_wakeup_lat_helper(req_dev, dev, t);
+
+ return ret;
+}
+
+/* WARNING: Device drivers need to now use pm_qos directly. */
+int omap_pm_set_max_sdma_lat(struct pm_qos_request_list **qos_request, long t)
+{
+ WARN(1, "Deprecated %s: Driver should use pm_qos to add request\n",
+ __func__);
+
+ return -EINVAL;
+}
+
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return -EINVAL;
+}
+
+/*
+ * DSP Bridge-specific constraints
+ * WARNING: Device drivers need to now use opp layer/omap_device_scale directly.
+ */
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return ERR_PTR(-EINVAL);
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return;
+}
+
+int omap_pm_set_min_mpu_freq(struct device *dev, unsigned long f)
+{
+ WARN(1, "Deprecated %s: Driver should NOT use this function\n",
+ __func__);
+
+ return -EINVAL;
+
+}
+
+EXPORT_SYMBOL(omap_pm_set_min_mpu_freq);
+
+u8 omap_pm_dsp_get_opp(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return ERR_PTR(-EINVAL);
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return;
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return 0;
+}
+
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+ off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+ off_mode_enabled = false;
+}
+
+/*
+ * Device context loss tracking
+ * WARNING: at this point we dont have a reliable context loss reporting
+ * mechanism. Instead, we ensure that we report context loss always.
+ */
+int omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+ static u32 count = 1;
+
+ if (!dev) {
+ WARN_ON(1);
+ return -EINVAL;
+ };
+
+ count++;
+
+ /*
+ * Context loss count has to be a non-negative value.
+ * Clear the sign bit to get a value range from 0 to
+ * INT_MAX. Roll over to 1
+ */
+ count = (count & ~INT_MAX) ? 1 : count;
+
+ pr_debug("OMAP PM: returning context loss count for dev %s count %ul\n",
+ dev_name(dev), count);
+ return count;
+}
+
+/* Should be called before clk framework init */
+int __init omap_pm_if_early_init(void)
+{
+ return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(void)
+{
+ return omap_pm_if_init_helper();
+}
+
+void omap_pm_if_exit(void)
+{
+ /* Deallocate CPUFreq frequency table here */
+}
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
deleted file mode 100644
index b0471bb2..0000000
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * omap-pm-noop.c - OMAP power management interface - dummy version
- *
- * This code implements the OMAP power management interface to
- * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for
- * debug/demonstration use, as it does nothing but printk() whenever a
- * function is called (when DEBUG is defined, below)
- *
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
- * Paul Walmsley
- *
- * Interface developed by (in alphabetical order):
- * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
- * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
- */
-
-#undef DEBUG
-
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-
-/* Interface documentation is in mach/omap-pm.h */
-#include <plat/omap-pm.h>
-#include <plat/omap_device.h>
-
-static bool off_mode_enabled;
-static u32 dummy_context_loss_counter;
-
-/*
- * Device-driver-originated constraints (via board-*.c files)
- */
-
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- };
-
- if (t == -1)
- pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the MPU to a
- * powerdomain, then go through the list of current max lat
- * constraints on the MPU and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
-{
- if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
- agent_id != OCP_TARGET_AGENT)) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- };
-
- if (r == 0)
- pr_debug("OMAP PM: remove min bus tput constraint: "
- "dev %s for agent_id %d\n", dev_name(dev), agent_id);
- else
- pr_debug("OMAP PM: add min bus tput constraint: "
- "dev %s for agent_id %d: rate %ld KiB\n",
- dev_name(dev), agent_id, r);
-
- /*
- * This code should model the interconnect and compute the
- * required clock frequency, convert that to a VDD2 OPP ID, then
- * set the VDD2 OPP appropriately.
- *
- * TI CDP code can call constraint_set here on the VDD2 OPP.
- */
-
- return 0;
-}
-
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
- long t)
-{
- if (!req_dev || !dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- };
-
- if (t == -1)
- pr_debug("OMAP PM: remove max device latency constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add max device latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the device to a
- * powerdomain, then go through the list of current max lat
- * constraints on that powerdomain and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state. Conceivably, this code should also determine
- * whether to actually disable the device clocks or not,
- * depending on how long it takes to re-enable the clocks.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- };
-
- if (t == -1)
- pr_debug("OMAP PM: remove max DMA latency constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add max DMA latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
-
- /*
- * For current Linux PM QOS params, this code should scan the
- * list of maximum CPU and DMA latencies and select the
- * smallest, then set cpu_dma_latency pm_qos_param
- * accordingly.
- *
- * For future Linux PM QOS params, with separate CPU and DMA
- * latency params, this code should just set the dma_latency param.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
-{
- if (!dev || !c || r < 0) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (r == 0)
- pr_debug("OMAP PM: remove min clk rate constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add min clk rate constraint: "
- "dev %s, rate = %ld Hz\n", dev_name(dev), r);
-
- /*
- * Code in a real implementation should keep track of these
- * constraints on the clock, and determine the highest minimum
- * clock rate. It should iterate over each OPP and determine
- * whether the OPP will result in a clock rate that would
- * satisfy this constraint (and any other PM constraint in effect
- * at that time). Once it finds the lowest-voltage OPP that
- * meets those conditions, it should switch to it, or return
- * an error if the code is not capable of doing so.
- */
-
- return 0;
-}
-
-/*
- * DSP Bridge-specific constraints
- */
-
-const struct omap_opp *omap_pm_dsp_get_opp_table(void)
-{
- pr_debug("OMAP PM: DSP request for OPP table\n");
-
- /*
- * Return DSP frequency table here: The final item in the
- * array should have .rate = .opp_id = 0.
- */
-
- return NULL;
-}
-
-void omap_pm_dsp_set_min_opp(u8 opp_id)
-{
- if (opp_id == 0) {
- WARN_ON(1);
- return;
- }
-
- pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
-
- /*
- *
- * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
- * can just test to see which is higher, the CPU's desired OPP
- * ID or the DSP's desired OPP ID, and use whichever is
- * highest.
- *
- * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
- * rate is keyed on MPU speed, not the OPP ID. So we need to
- * map the OPP ID to the MPU speed for use with clk_set_rate()
- * if it is higher than the current OPP clock rate.
- *
- */
-}
-
-
-u8 omap_pm_dsp_get_opp(void)
-{
- pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
-
- /*
- * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
- *
- * CDP12.14+:
- * Call clk_get_rate() on the OPP custom clock, map that to an
- * OPP ID using the tables defined in board-*.c/chip-*.c files.
- */
-
- return 0;
-}
-
-/*
- * CPUFreq-originated constraint
- *
- * In the future, this should be handled by custom OPP clocktype
- * functions.
- */
-
-struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
-{
- pr_debug("OMAP PM: CPUFreq request for frequency table\n");
-
- /*
- * Return CPUFreq frequency table here: loop over
- * all VDD1 clkrates, pull out the mpu_ck frequencies, build
- * table
- */
-
- return NULL;
-}
-
-void omap_pm_cpu_set_freq(unsigned long f)
-{
- if (f == 0) {
- WARN_ON(1);
- return;
- }
-
- pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
- f);
-
- /*
- * For l-o dev tree, determine whether MPU freq or DSP OPP id
- * freq is higher. Find the OPP ID corresponding to the
- * higher frequency. Call clk_round_rate() and clk_set_rate()
- * on the OPP custom clock.
- *
- * CDP should just be able to set the VDD1 OPP clock rate here.
- */
-}
-
-unsigned long omap_pm_cpu_get_freq(void)
-{
- pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
-
- /*
- * Call clk_get_rate() on the mpu_ck.
- */
-
- return 0;
-}
-
-/**
- * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
- *
- * Intended for use only by OMAP PM core code to notify this layer
- * that off mode has been enabled.
- */
-void omap_pm_enable_off_mode(void)
-{
- off_mode_enabled = true;
-}
-
-/**
- * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
- *
- * Intended for use only by OMAP PM core code to notify this layer
- * that off mode has been disabled.
- */
-void omap_pm_disable_off_mode(void)
-{
- off_mode_enabled = false;
-}
-
-/*
- * Device context loss tracking
- */
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-
-u32 omap_pm_get_dev_context_loss_count(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- u32 count;
-
- if (WARN_ON(!dev))
- return 0;
-
- if (dev->parent == &omap_device_parent) {
- count = omap_device_get_context_loss_count(pdev);
- } else {
- WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
- dev_name(dev));
- if (off_mode_enabled)
- dummy_context_loss_counter++;
- count = dummy_context_loss_counter;
- }
-
- pr_debug("OMAP PM: context loss count for dev %s = %d\n",
- dev_name(dev), count);
-
- return count;
-}
-
-#else
-
-u32 omap_pm_get_dev_context_loss_count(struct device *dev)
-{
- return dummy_context_loss_counter;
-}
-
-#endif
-
-/* Should be called before clk framework init */
-int __init omap_pm_if_early_init(void)
-{
- return 0;
-}
-
-/* Must be called after clock framework is initialized */
-int __init omap_pm_if_init(void)
-{
- return 0;
-}
-
-void omap_pm_if_exit(void)
-{
- /* Deallocate CPUFreq frequency table here */
-}
-
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index a37b8eb..92b4496 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -84,6 +84,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/pm_runtime.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
@@ -145,12 +146,12 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
odpl->activate_lat_worst = act_lat;
if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
odpl->activate_lat = act_lat;
- pr_warning("omap_device: %s.%d: new worst case "
+ pr_debug("omap_device: %s.%d: new worst case "
"activate latency %d: %llu\n",
od->pdev.name, od->pdev.id,
od->pm_lat_level, act_lat);
} else
- pr_warning("omap_device: %s.%d: activate "
+ pr_debug("omap_device: %s.%d: activate "
"latency %d higher than exptected. "
"(%llu > %d)\n",
od->pdev.name, od->pdev.id,
@@ -213,12 +214,12 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
odpl->deactivate_lat_worst = deact_lat;
if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
odpl->deactivate_lat = deact_lat;
- pr_warning("omap_device: %s.%d: new worst case "
+ pr_debug("omap_device: %s.%d: new worst case "
"deactivate latency %d: %llu\n",
od->pdev.name, od->pdev.id,
od->pm_lat_level, deact_lat);
} else
- pr_warning("omap_device: %s.%d: deactivate "
+ pr_debug("omap_device: %s.%d: deactivate "
"latency %d higher than exptected. "
"(%llu > %d)\n",
od->pdev.name, od->pdev.id,
@@ -310,7 +311,7 @@ static void _add_optional_clock_clkdev(struct omap_device *od,
* return the context loss counter for that hwmod, otherwise return
* zero.
*/
-u32 omap_device_get_context_loss_count(struct platform_device *pdev)
+int omap_device_get_context_loss_count(struct platform_device *pdev)
{
struct omap_device *od;
u32 ret = 0;
@@ -539,20 +540,34 @@ int omap_early_device_register(struct omap_device *od)
static int _od_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
+ int ret;
+
+ ret = pm_generic_runtime_suspend(dev);
+
+ if (!ret)
+ omap_device_idle(pdev);
+
+ return ret;
+}
- return omap_device_idle(pdev);
+static int _od_runtime_idle(struct device *dev)
+{
+ return pm_generic_runtime_idle(dev);
}
static int _od_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- return omap_device_enable(pdev);
+ omap_device_enable(pdev);
+
+ return pm_generic_runtime_resume(dev);
}
static struct dev_power_domain omap_device_power_domain = {
.ops = {
.runtime_suspend = _od_runtime_suspend,
+ .runtime_idle = _od_runtime_idle,
.runtime_resume = _od_runtime_resume,
USE_PLATFORM_PM_SLEEP_OPS
}
diff --git a/arch/arm/plat-omap/omap_rpmsg.c b/arch/arm/plat-omap/omap_rpmsg.c
index d7c1e58..f3edc84 100644
--- a/arch/arm/plat-omap/omap_rpmsg.c
+++ b/arch/arm/plat-omap/omap_rpmsg.c
@@ -397,11 +397,13 @@ static struct virtio_config_ops omap_rpmsg_config_ops = {
};
static struct rpmsg_channel_info omap_ipuc0_hardcoded_chnls[] = {
+ { "rpmsg-resmgr", 100, RPMSG_ADDR_ANY },
{ "rpmsg-server-sample", 137, RPMSG_ADDR_ANY },
{ },
};
static struct rpmsg_channel_info omap_ipuc1_hardcoded_chnls[] = {
+ { "rpmsg-resmgr", 100, RPMSG_ADDR_ANY },
{ },
};