aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap1/common.h2
-rw-r--r--arch/arm/mach-omap1/devices.c21
-rw-r--r--arch/arm/mach-omap1/reset.c41
-rw-r--r--arch/arm/mach-omap2/Makefile115
-rw-r--r--arch/arm/mach-omap2/am33xx.h1
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c2
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c2
-rw-r--r--arch/arm/mach-omap2/board-apollon.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c18
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c2
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c2
-rw-r--r--arch/arm/mach-omap2/board-generic.c10
-rw-r--r--arch/arm/mach-omap2/board-h4.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c4
-rw-r--r--arch/arm/mach-omap2/board-ldp.c2
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c6
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c4
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c2
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c2
-rw-r--r--arch/arm/mach-omap2/board-overo.c2
-rw-r--r--arch/arm/mach-omap2/board-rm680.c4
-rw-r--r--arch/arm/mach-omap2/board-rx51.c2
-rw-r--r--arch/arm/mach-omap2/board-ti8168evm.c4
-rw-r--r--arch/arm/mach-omap2/board-zoom.c4
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c59
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpll.c2
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c36
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c70
-rw-r--r--arch/arm/mach-omap2/clkt_iclk.c1
-rw-r--r--arch/arm/mach-omap2/clock.c60
-rw-r--r--arch/arm/mach-omap2/clock.h28
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c28
-rw-r--r--arch/arm/mach-omap2/clock2430.c2
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c28
-rw-r--r--arch/arm/mach-omap2/clock2xxx.c16
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h9
-rw-r--r--arch/arm/mach-omap2/clock34xx.c2
-rw-r--r--arch/arm/mach-omap2/clock3517.c2
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c341
-rw-r--r--arch/arm/mach-omap2/clockdomain33xx.c74
-rw-r--r--arch/arm/mach-omap2/clockdomain44xx.c151
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h2
-rw-r--r--arch/arm/mach-omap2/cm.h30
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c381
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h70
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h125
-rw-r--r--arch/arm/mach-omap2/cm33xx.c56
-rw-r--r--arch/arm/mach-omap2/cm3xxx.c (renamed from arch/arm/mach-omap2/cm2xxx_3xxx.c)371
-rw-r--r--arch/arm/mach-omap2/cm3xxx.h91
-rw-r--r--arch/arm/mach-omap2/cm_common.c140
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c142
-rw-r--r--arch/arm/mach-omap2/cminst44xx.h2
-rw-r--r--arch/arm/mach-omap2/common.c183
-rw-r--r--arch/arm/mach-omap2/common.h133
-rw-r--r--arch/arm/mach-omap2/control.c14
-rw-r--r--arch/arm/mach-omap2/control.h2
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c1
-rw-r--r--arch/arm/mach-omap2/devices.c26
-rw-r--r--arch/arm/mach-omap2/display.c2
-rw-r--r--arch/arm/mach-omap2/hdq1w.c4
-rw-r--r--arch/arm/mach-omap2/i2c.c6
-rw-r--r--arch/arm/mach-omap2/id.c7
-rw-r--r--arch/arm/mach-omap2/io.c85
-rw-r--r--arch/arm/mach-omap2/mcbsp.c2
-rw-r--r--arch/arm/mach-omap2/msdi.c4
-rw-r--r--arch/arm/mach-omap2/omap2-restart.c65
-rw-r--r--arch/arm/mach-omap2/omap3-restart.c36
-rw-r--r--arch/arm/mach-omap2/omap4-common.c19
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c59
-rw-r--r--arch/arm/mach-omap2/pm24xx.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c6
-rw-r--r--arch/arm/mach-omap2/powerdomain.c2
-rw-r--r--arch/arm/mach-omap2/powerdomain2xxx_3xxx.c242
-rw-r--r--arch/arm/mach-omap2/powerdomain33xx.c229
-rw-r--r--arch/arm/mach-omap2/powerdomain44xx.c285
-rw-r--r--arch/arm/mach-omap2/prcm-common.h22
-rw-r--r--arch/arm/mach-omap2/prcm.c189
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.c17
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.h9
-rw-r--r--arch/arm/mach-omap2/prm-regbits-24xx.h6
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h12
-rw-r--r--arch/arm/mach-omap2/prm.h77
-rw-r--r--arch/arm/mach-omap2/prm2xxx.c139
-rw-r--r--arch/arm/mach-omap2/prm2xxx.h134
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c332
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h284
-rw-r--r--arch/arm/mach-omap2/prm33xx.c202
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c417
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h162
-rw-r--r--arch/arm/mach-omap2/prm44xx.c356
-rw-r--r--arch/arm/mach-omap2/prm44xx.h2
-rw-r--r--arch/arm/mach-omap2/prm_common.c117
-rw-r--r--arch/arm/mach-omap2/prminst44xx.h2
-rw-r--r--arch/arm/mach-omap2/sdrc.c8
-rw-r--r--arch/arm/mach-omap2/sdrc.h2
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c2
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S4
-rw-r--r--arch/arm/mach-omap2/sram242x.S4
-rw-r--r--arch/arm/mach-omap2/sram243x.S4
-rw-r--r--arch/arm/mach-omap2/sram34xx.S2
-rw-r--r--arch/arm/mach-omap2/ti81xx.h9
-rw-r--r--arch/arm/mach-omap2/wd_timer.c40
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h37
-rw-r--r--drivers/watchdog/omap_wdt.c26
-rw-r--r--include/linux/platform_data/omap-wd-timer.h38
114 files changed, 3728 insertions, 2936 deletions
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index fc8c9449eba8..b53e0854422f 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -93,4 +93,6 @@ extern int ocpi_enable(void);
static inline int ocpi_enable(void) { return 0; }
#endif
+extern u32 omap1_get_reset_sources(void);
+
#endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 7155ed8b97f8..0af635205e8a 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -17,6 +17,8 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/platform_data/omap-wd-timer.h>
+
#include <asm/mach/map.h>
#include <mach/tc.h>
@@ -447,18 +449,31 @@ static struct resource wdt_resources[] = {
};
static struct platform_device omap_wdt_device = {
- .name = "omap_wdt",
- .id = -1,
+ .name = "omap_wdt",
+ .id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
static int __init omap_init_wdt(void)
{
+ struct omap_wd_timer_platform_data pdata;
+ int ret;
+
if (!cpu_is_omap16xx())
return -ENODEV;
- return platform_device_register(&omap_wdt_device);
+ pdata.read_reset_sources = omap1_get_reset_sources;
+
+ ret = platform_device_register(&omap_wdt_device);
+ if (!ret) {
+ ret = platform_device_add_data(&omap_wdt_device, &pdata,
+ sizeof(pdata));
+ if (ret)
+ platform_device_del(&omap_wdt_device);
+ }
+
+ return ret;
}
subsys_initcall(omap_init_wdt);
#endif
diff --git a/arch/arm/mach-omap1/reset.c b/arch/arm/mach-omap1/reset.c
index b17709103866..5eebd7e889d0 100644
--- a/arch/arm/mach-omap1/reset.c
+++ b/arch/arm/mach-omap1/reset.c
@@ -4,12 +4,24 @@
#include <linux/kernel.h>
#include <linux/io.h>
-#include <plat/prcm.h>
-
#include <mach/hardware.h>
+#include "iomap.h"
#include "common.h"
+/* ARM_SYSST bit shifts related to SoC reset sources */
+#define ARM_SYSST_POR_SHIFT 5
+#define ARM_SYSST_EXT_RST_SHIFT 4
+#define ARM_SYSST_ARM_WDRST_SHIFT 2
+#define ARM_SYSST_GLOB_SWRST_SHIFT 1
+
+/* Standardized reset source bits (across all OMAP SoCs) */
+#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
+#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
+#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
+#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
+
+
void omap1_restart(char mode, const char *cmd)
{
/*
@@ -23,3 +35,28 @@ void omap1_restart(char mode, const char *cmd)
omap_writew(1, ARM_RSTCT1);
}
+
+/**
+ * omap1_get_reset_sources - return the source of the SoC's last reset
+ *
+ * Returns bits that represent the last reset source for the SoC. The
+ * format is standardized across OMAPs for use by the OMAP watchdog.
+ */
+u32 omap1_get_reset_sources(void)
+{
+ u32 ret = 0;
+ u16 rs;
+
+ rs = __raw_readw(OMAP1_IO_ADDRESS(ARM_SYSST));
+
+ if (rs & (1 << ARM_SYSST_POR_SHIFT))
+ ret |= 1 << OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT;
+ if (rs & (1 << ARM_SYSST_EXT_RST_SHIFT))
+ ret |= 1 << OMAP_EXTWARM_RST_SRC_ID_SHIFT;
+ if (rs & (1 << ARM_SYSST_ARM_WDRST_SHIFT))
+ ret |= 1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT;
+ if (rs & (1 << ARM_SYSST_GLOB_SWRST_SHIFT))
+ ret |= 1 << OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT;
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b118ed5f61a9..78cbb8c5992e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -7,28 +7,34 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
omap_device.o sram.o
-# INTCPS IP block support - XXX should be moved to drivers/
-obj-$(CONFIG_ARCH_OMAP2) += irq.o
-obj-$(CONFIG_ARCH_OMAP3) += irq.o
-obj-$(CONFIG_SOC_AM33XX) += irq.o
-
-# Secure monitor API support
-obj-$(CONFIG_ARCH_OMAP3) += omap-smc.o omap-secure.o
-obj-$(CONFIG_ARCH_OMAP4) += omap-smc.o omap-secure.o
-obj-$(CONFIG_SOC_OMAP5) += omap-smc.o omap-secure.o
+omap-2-3-common = irq.o
+hwmod-common = omap_hwmod.o \
+ omap_hwmod_common_data.o
+clock-common = clock.o clock_common_data.o \
+ clkt_dpll.o clkt_clksel.o
+secure-common = omap-smc.o omap-secure.o
+
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
+obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common)
ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
obj-y += mcbsp.o
endif
-obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
# SMP support ONLY available for OMAP4
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
-obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o
-obj-$(CONFIG_SOC_OMAP5) += omap4-common.o omap-wakeupgen.o
+omap-4-5-common = omap4-common.o omap-wakeupgen.o \
+ sleep44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common)
+obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common)
plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -44,6 +50,11 @@ AFLAGS_sram242x.o :=-Wa,-march=armv6
AFLAGS_sram243x.o :=-Wa,-march=armv6
AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
+# Restart code (OMAP4/5 currently in omap4-common.c)
+obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o
+obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o
+obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o
+
# Pin multiplexing
obj-$(CONFIG_SOC_OMAP2420) += mux2420.o
obj-$(CONFIG_SOC_OMAP2430) += mux2430.o
@@ -53,7 +64,6 @@ obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
# SMS/SDRC
obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
-obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
# OPP table initialization
ifeq ($(CONFIG_PM_OPP),y)
@@ -64,16 +74,16 @@ endif
# Power Management
ifeq ($(CONFIG_PM),y)
-obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o sleep24xx.o
+obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
-obj-$(CONFIG_ARCH_OMAP4) += sleep44xx.o
-obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o sleep44xx.o
+obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
-obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
+obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
AFLAGS_sleep24xx.o :=-Wa,-march=armv6
AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -85,76 +95,82 @@ endif
endif
ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
+obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
endif
# PRCM
-obj-y += prcm.o prm_common.o
-obj-$(CONFIG_ARCH_OMAP2) += cm2xxx_3xxx.o prm2xxx_3xxx.o
-obj-$(CONFIG_ARCH_OMAP3) += cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-y += prm_common.o cm_common.o
+obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o
omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \
prcm_mpu44xx.o prminst44xx.o \
- vc44xx_data.o vp44xx_data.o \
- prm44xx.o
+ vc44xx_data.o vp44xx_data.o
obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common)
# OMAP voltage domains
-obj-y += voltage.o vc.o vp.o
+voltagedomain-common := voltage.o vc.o vp.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common)
obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common)
obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o
-obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o
+obj-$(CONFIG_SOC_AM33XX) += $(voltagedomain-common)
+obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o
+obj-$(CONFIG_SOC_OMAP5) += $(voltagedomain-common)
# OMAP powerdomain framework
-obj-y += powerdomain.o powerdomain-common.o
+powerdomain-common += powerdomain.o powerdomain-common.o
+obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common)
obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o
-obj-$(CONFIG_ARCH_OMAP2) += powerdomain2xxx_3xxx.o
obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP3) += powerdomain2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common)
obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
-obj-$(CONFIG_SOC_AM33XX) += powerdomain33xx.o
+obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common)
obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o
-obj-$(CONFIG_SOC_OMAP5) += powerdomain44xx.o
+obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common)
# PRCM clockdomain control
-obj-y += clockdomain.o
-obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o
+clockdomain-common += clockdomain.o
+obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common)
obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o
obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
-obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common)
obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
-obj-$(CONFIG_SOC_AM33XX) += clockdomain33xx.o
+obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common)
obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o
-obj-$(CONFIG_SOC_OMAP5) += clockdomain44xx.o
+obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common)
# Clock framework
-obj-y += clock.o clock_common_data.o \
- clkt_dpll.o clkt_clksel.o
-obj-$(CONFIG_ARCH_OMAP2) += clock2xxx.o
-obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o clkt2xxx_sys.o
+obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
-obj-$(CONFIG_ARCH_OMAP3) += clock3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
-obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP4) += clock44xx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o
obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
-obj-$(CONFIG_SOC_AM33XX) += dpll3xxx.o clock33xx_data.o
+obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o
+obj-$(CONFIG_SOC_AM33XX) += clock33xx_data.o
+obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
# OMAP2 clock rate set data (old "OPP" data)
@@ -162,7 +178,6 @@ obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
# hwmod data
-obj-y += omap_hwmod_common_data.o
obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o
obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o
obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o
@@ -208,10 +223,10 @@ obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
-obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
+obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
-obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
-obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
+obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
+obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o
obj-$(CONFIG_MACH_OVERO) += board-overo.o
obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
diff --git a/arch/arm/mach-omap2/am33xx.h b/arch/arm/mach-omap2/am33xx.h
index 06c19bb7bca6..43296c1af9ee 100644
--- a/arch/arm/mach-omap2/am33xx.h
+++ b/arch/arm/mach-omap2/am33xx.h
@@ -21,5 +21,6 @@
#define AM33XX_SCM_BASE 0x44E10000
#define AM33XX_CTRL_BASE AM33XX_SCM_BASE
#define AM33XX_PRCM_BASE 0x44E00000
+#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + 0x3FC)
#endif /* __ASM_ARCH_AM33XX_H */
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index d1c01625fe5a..4815ea6f8f5d 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -285,5 +285,5 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
.init_machine = omap_2430sdp_init,
.init_late = omap2430_init_late,
.timer = &omap2_timer,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 79fd9048fd79..6601754f9512 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -597,5 +597,5 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
.init_machine = omap_3430sdp_init,
.init_late = omap3430_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 81871b1c735c..050aaa771254 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -212,5 +212,5 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
.init_machine = omap_sdp_init,
.init_late = omap3630_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index fd80d976872d..85dfa71e0dc6 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -881,5 +881,5 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
.init_machine = omap_4430sdp_init,
.init_late = omap4430_init_late,
.timer = &omap4_timer,
- .restart = omap_prcm_restart,
+ .restart = omap44xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index 603503c587b7..51b96a1206d1 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -93,5 +93,5 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
.init_machine = am3517_crane_init,
.init_late = am35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 96d6c5ab5d4c..4be58fd071f6 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -393,5 +393,5 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
.init_machine = am3517_evm_init,
.init_late = am35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 64cf1bde0f3b..5d0a61f54165 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -338,5 +338,5 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
.init_machine = omap_apollon_init,
.init_late = omap2420_init_late,
.timer = &omap2_timer,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index a8cad2237a2a..c8e37dc00892 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -751,18 +751,18 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
.init_machine = cm_t35_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
MACHINE_START(CM_T3730, "Compulab CM-T3730")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = omap3630_init_early,
- .init_irq = omap3_init_irq,
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
- .init_machine = cm_t3730_init,
+ .init_machine = cm_t3730_init,
.init_late = omap3630_init_late,
- .timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .timer = &omap3_timer,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 278664731d2c..699caec8f9e2 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -298,5 +298,5 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517")
.init_machine = cm_t3517_init,
.init_late = am35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 933479e36737..7667eb749522 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -643,5 +643,5 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
.init_machine = devkit8000_init,
.init_late = omap35xx_init_late,
.timer = &omap3_secure_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 601ecdfb1cf9..475e14f07216 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -57,7 +57,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
.init_machine = omap_generic_init,
.timer = &omap2_timer,
.dt_compat = omap242x_boards_compat,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
#endif
@@ -76,7 +76,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
.init_machine = omap_generic_init,
.timer = &omap2_timer,
.dt_compat = omap243x_boards_compat,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
#endif
@@ -95,7 +95,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
.init_machine = omap_generic_init,
.timer = &omap3_timer,
.dt_compat = omap3_boards_compat,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
#endif
@@ -134,7 +134,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
.init_late = omap4430_init_late,
.timer = &omap4_timer,
.dt_compat = omap4_boards_compat,
- .restart = omap_prcm_restart,
+ .restart = omap44xx_restart,
MACHINE_END
#endif
@@ -154,6 +154,6 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
.init_machine = omap_generic_init,
.timer = &omap5_timer,
.dt_compat = omap5_boards_compat,
- .restart = omap_prcm_restart,
+ .restart = omap44xx_restart,
MACHINE_END
#endif
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 8668c72ee810..b626dbe6f7bc 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -386,5 +386,5 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
.init_machine = omap_h4_init,
.init_late = omap2420_init_late,
.timer = &omap2_timer,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index dbc705ac4334..cea5d5292628 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -651,7 +651,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
.init_machine = igep_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
MACHINE_START(IGEP0030, "IGEP OMAP3 module")
@@ -664,5 +664,5 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.init_machine = igep_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 1164b1061038..0869f4f3d3e1 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -436,5 +436,5 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
.init_machine = omap_ldp_init,
.init_late = omap3430_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index e3efcb88cb3b..a4e167c55c1d 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -690,7 +690,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800")
.init_machine = n8x0_init_machine,
.init_late = omap2420_init_late,
.timer = &omap2_timer,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
MACHINE_START(NOKIA_N810, "Nokia N810")
@@ -703,7 +703,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810")
.init_machine = n8x0_init_machine,
.init_late = omap2420_init_late,
.timer = &omap2_timer,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
@@ -716,5 +716,5 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
.init_machine = n8x0_init_machine,
.init_late = omap2420_init_late,
.timer = &omap2_timer,
- .restart = omap_prcm_restart,
+ .restart = omap2xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 5a3800da903f..22c483d5dfa8 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -545,5 +545,5 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
.init_machine = omap3_beagle_init,
.init_late = omap3_init_late,
.timer = &omap3_secure_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 3c0b9a90f3b3..54647d6286b4 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -757,5 +757,5 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM")
.init_machine = omap3_evm_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index e84e2a875378..2a065ba6eb58 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -232,7 +232,7 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
.init_machine = omap3logic_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
@@ -245,5 +245,5 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
.init_machine = omap3logic_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index ce31bd329f38..a53a6683c1b8 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -619,5 +619,5 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
.init_machine = omap3pandora_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index ba1124538b9c..d8638b3b4f94 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -427,5 +427,5 @@ MACHINE_START(SBC3530, "OMAP3 STALKER")
.init_machine = omap3_stalker_init,
.init_late = omap35xx_init_late,
.timer = &omap3_secure_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index a225d819633f..263cb9cfbf37 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -387,5 +387,5 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
.init_machine = omap3_touchbook_init,
.init_late = omap3430_init_late,
.timer = &omap3_secure_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 8c00b99cd2a3..12a3a24d5bb5 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -524,5 +524,5 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
.init_machine = omap4_panda_init,
.init_late = omap4430_init_late,
.timer = &omap4_timer,
- .restart = omap_prcm_restart,
+ .restart = omap44xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index f5ba43fa0400..c8fde3e56441 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -552,5 +552,5 @@ MACHINE_START(OVERO, "Gumstix Overo")
.init_machine = overo_init,
.init_late = omap35xx_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 1997e0e722a1..cbcb1b2dc31f 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -148,7 +148,7 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
.init_machine = rm680_init,
.init_late = omap3630_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
@@ -161,5 +161,5 @@ MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
.init_machine = rm680_init,
.init_late = omap3630_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index c388aec14799..bf8f74b0ce3e 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -127,5 +127,5 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
.init_machine = rx51_init,
.init_late = omap3430_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index 5e672c2b6a43..1a3e056d63a7 100644
--- a/arch/arm/mach-omap2/board-ti8168evm.c
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -46,7 +46,7 @@ MACHINE_START(TI8168EVM, "ti8168evm")
.timer = &omap3_timer,
.init_machine = ti81xx_evm_init,
.init_late = ti81xx_init_late,
- .restart = omap_prcm_restart,
+ .restart = omap44xx_restart,
MACHINE_END
MACHINE_START(TI8148EVM, "ti8148evm")
@@ -58,5 +58,5 @@ MACHINE_START(TI8148EVM, "ti8148evm")
.timer = &omap3_timer,
.init_machine = ti81xx_evm_init,
.init_late = ti81xx_init_late,
- .restart = omap_prcm_restart,
+ .restart = omap44xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 8feb4d99b96d..d7fa31e67238 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -138,7 +138,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
.init_machine = omap_zoom_init,
.init_late = omap3430_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
@@ -151,5 +151,5 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
.init_machine = omap_zoom_init,
.init_late = omap3630_init_late,
.timer = &omap3_timer,
- .restart = omap_prcm_restart,
+ .restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index 73a1414b89b0..8c5b13e7ee61 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -21,11 +21,10 @@
#include <linux/clk.h>
#include <linux/io.h>
-#include <plat/prcm.h>
#include "clock.h"
#include "clock2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
@@ -37,44 +36,16 @@
#define APLLS_CLKIN_13MHZ 2
#define APLLS_CLKIN_12MHZ 3
-void __iomem *cm_idlest_pll;
-
/* Private functions */
-/* Enable an APLL if off */
-static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
-{
- u32 cval, apll_mask;
-
- apll_mask = EN_APLL_LOCKED << clk->enable_bit;
-
- cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-
- if ((cval & apll_mask) == apll_mask)
- return 0; /* apll already enabled */
-
- cval &= ~apll_mask;
- cval |= apll_mask;
- omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-
- omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
- OMAP24XX_CM_IDLEST_VAL, __clk_get_name(clk));
-
- /*
- * REVISIT: Should we return an error code if omap2_wait_clock_ready()
- * fails?
- */
- return 0;
-}
-
-static int omap2_clk_apll96_enable(struct clk *clk)
+static int _apll96_enable(struct clk *clk)
{
- return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);
+ return omap2xxx_cm_apll96_enable();
}
-static int omap2_clk_apll54_enable(struct clk *clk)
+static int _apll54_enable(struct clk *clk)
{
- return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
+ return omap2xxx_cm_apll54_enable();
}
static void _apll96_allow_idle(struct clk *clk)
@@ -97,28 +68,28 @@ static void _apll54_deny_idle(struct clk *clk)
omap2xxx_cm_set_apll54_disable_autoidle();
}
-/* Stop APLL */
-static void omap2_clk_apll_disable(struct clk *clk)
+static void _apll96_disable(struct clk *clk)
{
- u32 cval;
+ omap2xxx_cm_apll96_disable();
+}
- cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
- cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
- omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+static void _apll54_disable(struct clk *clk)
+{
+ omap2xxx_cm_apll54_disable();
}
/* Public data */
const struct clkops clkops_apll96 = {
- .enable = omap2_clk_apll96_enable,
- .disable = omap2_clk_apll_disable,
+ .enable = _apll96_enable,
+ .disable = _apll96_disable,
.allow_idle = _apll96_allow_idle,
.deny_idle = _apll96_deny_idle,
};
const struct clkops clkops_apll54 = {
- .enable = omap2_clk_apll54_enable,
- .disable = omap2_clk_apll_disable,
+ .enable = _apll54_enable,
+ .disable = _apll54_disable,
.allow_idle = _apll54_allow_idle,
.deny_idle = _apll54_deny_idle,
};
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
index 0890ba94a282..399534c7843b 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -15,7 +15,7 @@
#include <linux/io.h>
#include "clock.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
/* Private functions */
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
index 0d2f14c2dcce..825e44cdf1cf 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -28,16 +28,22 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
#include "sram.h"
/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
+/*
+ * dpll_core_ck: pointer to the combined dpll_ck + core_ck on OMAP2xxx
+ * (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set
+ * during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
+ */
+static struct clk *dpll_core_ck;
+
/**
* omap2xxx_clk_get_core_rate - return the CORE_CLK rate
- * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
*
* Returns the CORE_CLK rate. CORE_CLK can have one of three rate
* sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
@@ -45,12 +51,14 @@
* struct clk *dpll_ck, which is a composite clock of dpll_ck and
* core_ck.
*/
-unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
+unsigned long omap2xxx_clk_get_core_rate(void)
{
long long core_clk;
u32 v;
- core_clk = omap2_get_dpll_rate(clk);
+ WARN_ON(!dpll_core_ck);
+
+ core_clk = omap2_get_dpll_rate(dpll_core_ck);
v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
v &= OMAP24XX_CORE_CLK_SRC_MASK;
@@ -98,7 +106,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
unsigned long omap2_dpllcore_recalc(struct clk *clk)
{
- return omap2xxx_clk_get_core_rate(clk);
+ return omap2xxx_clk_get_core_rate();
}
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
@@ -108,7 +116,7 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
struct prcm_config tmpset;
const struct dpll_data *dd;
- cur_rate = omap2xxx_clk_get_core_rate(dclk);
+ cur_rate = omap2xxx_clk_get_core_rate();
mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
@@ -169,3 +177,19 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
return 0;
}
+/**
+ * omap2xxx_clkt_dpllcore_init - clk init function for dpll_ck
+ * @clk: struct clk *dpll_ck
+ *
+ * Store a local copy of @clk in dpll_core_ck so other code can query
+ * the core rate without having to clk_get(), which can sleep. Must
+ * only be called once. No return value. XXX If the clock
+ * registration process is ever changed such that dpll_ck is no longer
+ * statically defined, this code may need to change to increment some
+ * kind of use count on dpll_ck.
+ */
+void omap2xxx_clkt_dpllcore_init(struct clk *clk)
+{
+ WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
+ dpll_core_ck = clk;
+}
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index a38ebb209721..1c2041fbd718 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -1,7 +1,7 @@
/*
* OMAP2xxx DVFS virtual clock functions
*
- * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2005-2008, 2012 Texas Instruments, Inc.
* Copyright (C) 2004-2010 Nokia Corporation
*
* Contacts:
@@ -37,7 +37,7 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
#include "sram.h"
@@ -45,6 +45,13 @@
const struct prcm_config *curr_prcm_set;
const struct prcm_config *rate_table;
+/*
+ * sys_ck_rate: the rate of the external high-frequency clock
+ * oscillator on the board. Set by the SoC-specific clock init code.
+ * Once set during a boot, will not change.
+ */
+static unsigned long sys_ck_rate;
+
/**
* omap2_table_mpu_recalc - just return the MPU speed
* @clk: virt_prcm_set struct clk
@@ -66,15 +73,14 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk)
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
{
const struct prcm_config *ptr;
- long highest_rate, sys_clk_rate;
+ long highest_rate;
highest_rate = -EINVAL;
- sys_clk_rate = __clk_get_rate(sclk);
for (ptr = rate_table; ptr->mpu_speed; ptr++) {
if (!(ptr->flags & cpu_mask))
continue;
- if (ptr->xtal_speed != sys_clk_rate)
+ if (ptr->xtal_speed != sys_ck_rate)
continue;
highest_rate = ptr->mpu_speed;
@@ -93,15 +99,12 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
const struct prcm_config *prcm;
unsigned long found_speed = 0;
unsigned long flags;
- long sys_clk_rate;
-
- sys_clk_rate = __clk_get_rate(sclk);
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
if (!(prcm->flags & cpu_mask))
continue;
- if (prcm->xtal_speed != sys_clk_rate)
+ if (prcm->xtal_speed != sys_ck_rate)
continue;
if (prcm->mpu_speed <= rate) {
@@ -117,7 +120,7 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
}
curr_prcm_set = prcm;
- cur_rate = omap2xxx_clk_get_core_rate(dclk);
+ cur_rate = omap2xxx_clk_get_core_rate();
if (prcm->dpll_speed == cur_rate / 2) {
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -167,3 +170,50 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
return 0;
}
+
+/**
+ * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate
+ * table sets matches the current CORE DPLL hardware rate
+ *
+ * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set'
+ * global to point to the active rate set when found; otherwise, sets
+ * it to NULL. No return value;
+ */
+void omap2xxx_clkt_vps_check_bootloader_rates(void)
+{
+ const struct prcm_config *prcm = NULL;
+ unsigned long rate;
+
+ rate = omap2xxx_clk_get_core_rate();
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sys_ck_rate)
+ continue;
+ if (prcm->dpll_speed <= rate)
+ break;
+ }
+ curr_prcm_set = prcm;
+}
+
+/**
+ * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate
+ *
+ * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS
+ * code. (The sys_ck rate does not -- or rather, must not -- change
+ * during kernel runtime.) Must be called after we have a valid
+ * sys_ck rate, but before the virt_prcm_set clock rate is
+ * recalculated. No return value.
+ */
+void omap2xxx_clkt_vps_late_init(void)
+{
+ struct clk *c;
+
+ c = clk_get(NULL, "sys_ck");
+ if (IS_ERR(c)) {
+ WARN(1, "could not locate sys_ck\n");
+ } else {
+ sys_ck_rate = clk_get_rate(c);
+ clk_put(c);
+ }
+}
diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c
index 7c8d41e49834..fe774a09dd0c 100644
--- a/arch/arm/mach-omap2/clkt_iclk.c
+++ b/arch/arm/mach-omap2/clkt_iclk.c
@@ -14,7 +14,6 @@
#include <linux/clk.h>
#include <linux/io.h>
-#include <plat/prcm.h>
#include "clock.h"
#include "clock2xxx.h"
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 8b30759f8f9e..e381d991092c 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -26,16 +26,24 @@
#include <asm/cpu.h>
-#include <plat/prcm.h>
#include <trace/events/power.h>
#include "soc.h"
#include "clockdomain.h"
#include "clock.h"
-#include "cm2xxx_3xxx.h"
+#include "cm.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
+#include "common.h"
+
+/*
+ * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait
+ * for a module to indicate that it is no longer in idle
+ */
+#define MAX_MODULE_ENABLE_WAIT 100000
u16 cpu_mask;
@@ -57,6 +65,40 @@ static DEFINE_SPINLOCK(clockfw_lock);
/* Private functions */
+
+/**
+ * _wait_idlest_generic - wait for a module to leave the idle state
+ * @reg: virtual address of module IDLEST register
+ * @mask: value to mask against to determine if the module is active
+ * @idlest: idle state indicator (0 or 1) for the clock
+ * @name: name of the clock (for printk)
+ *
+ * Wait for a module to leave idle, where its idle-status register is
+ * not inside the CM module. Returns 1 if the module left idle
+ * promptly, or 0 if the module did not leave idle before the timeout
+ * elapsed. XXX Deprecated - should be moved into drivers for the
+ * individual IP block that the IDLEST register exists in.
+ */
+static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest,
+ const char *name)
+{
+ int i = 0, ena = 0;
+
+ ena = (idlest) ? 0 : mask;
+
+ omap_test_timeout(((__raw_readl(reg) & mask) == ena),
+ MAX_MODULE_ENABLE_WAIT, i);
+
+ if (i < MAX_MODULE_ENABLE_WAIT)
+ pr_debug("omap clock: module associated with clock %s ready after %d loops\n",
+ name, i);
+ else
+ pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n",
+ name, MAX_MODULE_ENABLE_WAIT);
+
+ return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
+};
+
/**
* _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
* @clk: struct clk * belonging to the module
@@ -70,7 +112,9 @@ static DEFINE_SPINLOCK(clockfw_lock);
static void _omap2_module_wait_ready(struct clk *clk)
{
void __iomem *companion_reg, *idlest_reg;
- u8 other_bit, idlest_bit, idlest_val;
+ u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
+ s16 prcm_mod;
+ int r;
/* Not all modules have multiple clocks that their IDLEST depends on */
if (clk->ops->find_companion) {
@@ -81,8 +125,14 @@ static void _omap2_module_wait_ready(struct clk *clk)
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
- omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
- __clk_get_name(clk));
+ r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id);
+ if (r) {
+ /* IDLEST register not in the CM module */
+ _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val,
+ clk->name);
+ } else {
+ cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit);
+ };
}
/* Public functions */
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index cfba1ffe5cc2..ff9789bc0fd1 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -409,33 +409,6 @@ extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
u32 omap2_get_dpll_rate(struct clk *clk);
void omap2_init_dpll_parent(struct clk *clk);
-int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
-
-
-#ifdef CONFIG_ARCH_OMAP2
-void omap2xxx_clk_prepare_for_reboot(void);
-#else
-static inline void omap2xxx_clk_prepare_for_reboot(void)
-{
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-void omap3_clk_prepare_for_reboot(void);
-#else
-static inline void omap3_clk_prepare_for_reboot(void)
-{
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-void omap4_clk_prepare_for_reboot(void);
-#else
-static inline void omap4_clk_prepare_for_reboot(void)
-{
-}
-#endif
-
int omap2_dflt_clk_enable(struct clk *clk);
void omap2_dflt_clk_disable(struct clk *clk);
void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
@@ -454,7 +427,6 @@ extern const struct clkops clkops_dummy;
extern const struct clkops clkops_omap2_dflt;
extern struct clk_functions omap2_clk_functions;
-extern struct clk *vclk, *sclk;
extern const struct clksel_rate gpt_32k_rates[];
extern const struct clksel_rate gpt_sys_rates[];
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index ff47a6c2611d..608874b651e8 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1,7 +1,7 @@
/*
* OMAP2420 clock data
*
- * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
* Copyright (C) 2004-2011 Nokia Corporation
*
* Contacts:
@@ -23,7 +23,7 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
@@ -124,6 +124,7 @@ static struct clk dpll_ck = {
.name = "dpll_ck",
.ops = &clkops_omap2xxx_dpll_ops,
.parent = &sys_ck, /* Can be func_32k also */
+ .init = &omap2xxx_clkt_dpllcore_init,
.dpll_data = &dpll_dd,
.clkdm_name = "wkup_clkdm",
.recalc = &omap2_dpllcore_recalc,
@@ -1924,12 +1925,9 @@ static struct omap_clk omap2420_clks[] = {
int __init omap2420_clk_init(void)
{
- const struct prcm_config *prcm;
struct omap_clk *c;
- u32 clkrate;
prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
- cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
cpu_mask = RATE_IN_242X;
rate_table = omap2420_rate_table;
@@ -1949,20 +1947,13 @@ int __init omap2420_clk_init(void)
omap2_init_clk_clkdm(c->lk.clk);
}
+ omap2xxx_clkt_vps_late_init();
+
/* Disable autoidle on all clocks; let the PM code enable it later */
omap_clk_disable_autoidle_all();
- /* Check the MPU rate set by bootloader */
- clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
- if (prcm->xtal_speed != sys_ck.rate)
- continue;
- if (prcm->dpll_speed <= clkrate)
- break;
- }
- curr_prcm_set = prcm;
+ /* XXX Can this be done from the virt_prcm_set clk init function? */
+ omap2xxx_clkt_vps_check_bootloader_rates();
recalculate_root_clocks();
@@ -1976,11 +1967,6 @@ int __init omap2420_clk_init(void)
*/
clk_enable_init_clocks();
- /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
- vclk = clk_get(NULL, "virt_prcm_set");
- sclk = clk_get(NULL, "sys_ck");
- dclk = clk_get(NULL, "dpll_ck");
-
return 0;
}
diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c
index 850f83e8954f..e37df538bcd3 100644
--- a/arch/arm/mach-omap2/clock2430.c
+++ b/arch/arm/mach-omap2/clock2430.c
@@ -25,7 +25,7 @@
#include "iomap.h"
#include "clock.h"
#include "clock2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
/**
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index cab8e9c52d6e..b179b6ef4329 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1,7 +1,7 @@
/*
* OMAP2430 clock data
*
- * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
* Copyright (C) 2004-2011 Nokia Corporation
*
* Contacts:
@@ -22,7 +22,7 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
@@ -123,6 +123,7 @@ static struct clk dpll_ck = {
.name = "dpll_ck",
.ops = &clkops_omap2xxx_dpll_ops,
.parent = &sys_ck, /* Can be func_32k also */
+ .init = &omap2xxx_clkt_dpllcore_init,
.dpll_data = &dpll_dd,
.clkdm_name = "wkup_clkdm",
.recalc = &omap2_dpllcore_recalc,
@@ -2023,12 +2024,9 @@ static struct omap_clk omap2430_clks[] = {
int __init omap2430_clk_init(void)
{
- const struct prcm_config *prcm;
struct omap_clk *c;
- u32 clkrate;
prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
- cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
cpu_mask = RATE_IN_243X;
rate_table = omap2430_rate_table;
@@ -2048,20 +2046,13 @@ int __init omap2430_clk_init(void)
omap2_init_clk_clkdm(c->lk.clk);
}
+ omap2xxx_clkt_vps_late_init();
+
/* Disable autoidle on all clocks; let the PM code enable it later */
omap_clk_disable_autoidle_all();
- /* Check the MPU rate set by bootloader */
- clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
- if (prcm->xtal_speed != sys_ck.rate)
- continue;
- if (prcm->dpll_speed <= clkrate)
- break;
- }
- curr_prcm_set = prcm;
+ /* XXX Can this be done from the virt_prcm_set clk init function? */
+ omap2xxx_clkt_vps_check_bootloader_rates();
recalculate_root_clocks();
@@ -2075,11 +2066,6 @@ int __init omap2430_clk_init(void)
*/
clk_enable_init_clocks();
- /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
- vclk = clk_get(NULL, "virt_prcm_set");
- sclk = clk_get(NULL, "sys_ck");
- dclk = clk_get(NULL, "dpll_ck");
-
return 0;
}
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 5feee16fee0e..5f7faeb4c19b 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -28,27 +28,11 @@
#include "cm.h"
#include "cm-regbits-24xx.h"
-struct clk *vclk, *sclk, *dclk;
-
/*
* Omap24xx specific clock functions
*/
/*
- * Set clocks for bypass mode for reboot to work.
- */
-void omap2xxx_clk_prepare_for_reboot(void)
-{
- u32 rate;
-
- if (vclk == NULL || sclk == NULL)
- return;
-
- rate = clk_get_rate(sclk);
- clk_set_rate(vclk, rate);
-}
-
-/*
* Switch the MPU rate if specified on cmdline. We cannot do this
* early until cmdline is parsed. XXX This should be removed from the
* clock code and handled by the OPP layer code in the near future.
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index cb6df8ca9e4a..ce809c913b6f 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -15,10 +15,13 @@ unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
unsigned long omap2_osc_clk_recalc(struct clk *clk);
unsigned long omap2_dpllcore_recalc(struct clk *clk);
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
-unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
+unsigned long omap2xxx_clk_get_core_rate(void);
u32 omap2xxx_get_apll_clkin(void);
u32 omap2xxx_get_sysclkdiv(void);
void omap2xxx_clk_prepare_for_reboot(void);
+void omap2xxx_clkt_dpllcore_init(struct clk *clk);
+void omap2xxx_clkt_vps_check_bootloader_rates(void);
+void omap2xxx_clkt_vps_late_init(void);
#ifdef CONFIG_SOC_OMAP2420
int omap2420_clk_init(void);
@@ -32,9 +35,7 @@ int omap2430_clk_init(void);
#define omap2430_clk_init() do { } while(0)
#endif
-extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll;
-
-extern struct clk *dclk;
+extern void __iomem *prcm_clksrc_ctrl;
extern const struct clkops clkops_omap2430_i2chs_wait;
extern const struct clkops clkops_oscck;
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index baaaa4258708..e41819ba7482 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -23,7 +23,7 @@
#include "clock.h"
#include "clock34xx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
/**
diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c
index 80209050cd7a..622ea0502610 100644
--- a/arch/arm/mach-omap2/clock3517.c
+++ b/arch/arm/mach-omap2/clock3517.c
@@ -23,7 +23,7 @@
#include "clock.h"
#include "clock3517.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
/*
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index a02d158568e8..6cca19953950 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -28,7 +28,7 @@
#include "clock34xx.h"
#include "clock36xx.h"
#include "clock3517.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
#include "prm2xxx_3xxx.h"
#include "prm-regbits-34xx.h"
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
deleted file mode 100644
index 3e4e9209b2df..000000000000
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * OMAP2 and OMAP3 clockdomain control
- *
- * Copyright (C) 2008-2010 Texas Instruments, Inc.
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
- * 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 <plat/prcm.h>
-
-#include "soc.h"
-#include "prm.h"
-#include "prm2xxx_3xxx.h"
-#include "cm.h"
-#include "cm2xxx_3xxx.h"
-#include "cm-regbits-24xx.h"
-#include "cm-regbits-34xx.h"
-#include "prm-regbits-24xx.h"
-#include "clockdomain.h"
-
-static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
- return 0;
-}
-
-static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
- return 0;
-}
-
-static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
- PM_WKDEP, (1 << clkdm2->dep_bit));
-}
-
-static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
-{
- struct clkdm_dep *cd;
- u32 mask = 0;
-
- for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!cd->clkdm)
- continue; /* only happens if data is erroneous */
-
- /* PRM accesses are slow, so minimize them */
- mask |= 1 << cd->clkdm->dep_bit;
- atomic_set(&cd->wkdep_usecount, 0);
- }
-
- omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
- PM_WKDEP);
- return 0;
-}
-
-static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP);
- return 0;
-}
-
-static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP);
- return 0;
-}
-
-static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
-}
-
-static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
-{
- struct clkdm_dep *cd;
- u32 mask = 0;
-
- for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!cd->clkdm)
- continue; /* only happens if data is erroneous */
-
- /* PRM accesses are slow, so minimize them */
- mask |= 1 << cd->clkdm->dep_bit;
- atomic_set(&cd->sleepdep_usecount, 0);
- }
- omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP);
- return 0;
-}
-
-static int omap2_clkdm_sleep(struct clockdomain *clkdm)
-{
- omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
- clkdm->pwrdm.ptr->prcm_offs,
- OMAP2_PM_PWSTCTRL);
- return 0;
-}
-
-static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
-{
- omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
- clkdm->pwrdm.ptr->prcm_offs,
- OMAP2_PM_PWSTCTRL);
- return 0;
-}
-
-static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
-{
- if (atomic_read(&clkdm->usecount) > 0)
- _clkdm_add_autodeps(clkdm);
-
- omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-}
-
-static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
-{
- omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (atomic_read(&clkdm->usecount) > 0)
- _clkdm_del_autodeps(clkdm);
-}
-
-static void _enable_hwsup(struct clockdomain *clkdm)
-{
- if (cpu_is_omap24xx())
- omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- else if (cpu_is_omap34xx())
- omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-}
-
-static void _disable_hwsup(struct clockdomain *clkdm)
-{
- if (cpu_is_omap24xx())
- omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- else if (cpu_is_omap34xx())
- omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-}
-
-static int omap3_clkdm_sleep(struct clockdomain *clkdm)
-{
- omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- return 0;
-}
-
-static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
-{
- omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- return 0;
-}
-
-static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
-{
- bool hwsup = false;
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (hwsup) {
- /* Disable HW transitions when we are changing deps */
- _disable_hwsup(clkdm);
- _clkdm_add_autodeps(clkdm);
- _enable_hwsup(clkdm);
- } else {
- if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
- omap2_clkdm_wakeup(clkdm);
- }
-
- return 0;
-}
-
-static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
-{
- bool hwsup = false;
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (hwsup) {
- /* Disable HW transitions when we are changing deps */
- _disable_hwsup(clkdm);
- _clkdm_del_autodeps(clkdm);
- _enable_hwsup(clkdm);
- } else {
- if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
- omap2_clkdm_sleep(clkdm);
- }
-
- return 0;
-}
-
-static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
-{
- if (atomic_read(&clkdm->usecount) > 0)
- _clkdm_add_autodeps(clkdm);
-
- omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-}
-
-static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
-{
- omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (atomic_read(&clkdm->usecount) > 0)
- _clkdm_del_autodeps(clkdm);
-}
-
-static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
-{
- bool hwsup = false;
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- /*
- * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
- * more details on the unpleasant problem this is working
- * around
- */
- if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
- (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
- omap3_clkdm_wakeup(clkdm);
- return 0;
- }
-
- hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (hwsup) {
- /* Disable HW transitions when we are changing deps */
- _disable_hwsup(clkdm);
- _clkdm_add_autodeps(clkdm);
- _enable_hwsup(clkdm);
- } else {
- if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
- omap3_clkdm_wakeup(clkdm);
- }
-
- return 0;
-}
-
-static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
-{
- bool hwsup = false;
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- /*
- * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
- * more details on the unpleasant problem this is working
- * around
- */
- if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
- !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
- _enable_hwsup(clkdm);
- return 0;
- }
-
- hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (hwsup) {
- /* Disable HW transitions when we are changing deps */
- _disable_hwsup(clkdm);
- _clkdm_del_autodeps(clkdm);
- _enable_hwsup(clkdm);
- } else {
- if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
- omap3_clkdm_sleep(clkdm);
- }
-
- return 0;
-}
-
-struct clkdm_ops omap2_clkdm_operations = {
- .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
- .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
- .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
- .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
- .clkdm_sleep = omap2_clkdm_sleep,
- .clkdm_wakeup = omap2_clkdm_wakeup,
- .clkdm_allow_idle = omap2_clkdm_allow_idle,
- .clkdm_deny_idle = omap2_clkdm_deny_idle,
- .clkdm_clk_enable = omap2_clkdm_clk_enable,
- .clkdm_clk_disable = omap2_clkdm_clk_disable,
-};
-
-struct clkdm_ops omap3_clkdm_operations = {
- .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
- .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
- .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
- .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
- .clkdm_add_sleepdep = omap3_clkdm_add_sleepdep,
- .clkdm_del_sleepdep = omap3_clkdm_del_sleepdep,
- .clkdm_read_sleepdep = omap3_clkdm_read_sleepdep,
- .clkdm_clear_all_sleepdeps = omap3_clkdm_clear_all_sleepdeps,
- .clkdm_sleep = omap3_clkdm_sleep,
- .clkdm_wakeup = omap3_clkdm_wakeup,
- .clkdm_allow_idle = omap3_clkdm_allow_idle,
- .clkdm_deny_idle = omap3_clkdm_deny_idle,
- .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
- .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
-};
diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c
deleted file mode 100644
index aca6388fad76..000000000000
--- a/arch/arm/mach-omap2/clockdomain33xx.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * AM33XX clockdomain control
- *
- * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
- * Vaibhav Hiremath <hvaibhav@ti.com>
- *
- * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-
-#include "clockdomain.h"
-#include "cm33xx.h"
-
-
-static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
-{
- am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
- return 0;
-}
-
-static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
-{
- am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
- return 0;
-}
-
-static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
-{
- am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
-}
-
-static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
-{
- am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
-}
-
-static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
-{
- if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
- return am33xx_clkdm_wakeup(clkdm);
-
- return 0;
-}
-
-static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
-{
- bool hwsup = false;
-
- hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
-
- if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
- am33xx_clkdm_sleep(clkdm);
-
- return 0;
-}
-
-struct clkdm_ops am33xx_clkdm_operations = {
- .clkdm_sleep = am33xx_clkdm_sleep,
- .clkdm_wakeup = am33xx_clkdm_wakeup,
- .clkdm_allow_idle = am33xx_clkdm_allow_idle,
- .clkdm_deny_idle = am33xx_clkdm_deny_idle,
- .clkdm_clk_enable = am33xx_clkdm_clk_enable,
- .clkdm_clk_disable = am33xx_clkdm_clk_disable,
-};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
deleted file mode 100644
index 6fc6155625bc..000000000000
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * OMAP4 clockdomain control
- *
- * Copyright (C) 2008-2010 Texas Instruments, Inc.
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
- * 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/kernel.h>
-#include "clockdomain.h"
-#include "cminst44xx.h"
-#include "cm44xx.h"
-
-static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->prcm_partition,
- clkdm1->cm_inst, clkdm1->clkdm_offs +
- OMAP4_CM_STATICDEP);
- return 0;
-}
-
-static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->prcm_partition,
- clkdm1->cm_inst, clkdm1->clkdm_offs +
- OMAP4_CM_STATICDEP);
- return 0;
-}
-
-static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
- struct clockdomain *clkdm2)
-{
- return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
- clkdm1->cm_inst, clkdm1->clkdm_offs +
- OMAP4_CM_STATICDEP,
- (1 << clkdm2->dep_bit));
-}
-
-static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
-{
- struct clkdm_dep *cd;
- u32 mask = 0;
-
- if (!clkdm->prcm_partition)
- return 0;
-
- for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!cd->clkdm)
- continue; /* only happens if data is erroneous */
-
- mask |= 1 << cd->clkdm->dep_bit;
- atomic_set(&cd->wkdep_usecount, 0);
- }
-
- omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
- clkdm->cm_inst, clkdm->clkdm_offs +
- OMAP4_CM_STATICDEP);
- return 0;
-}
-
-static int omap4_clkdm_sleep(struct clockdomain *clkdm)
-{
- omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst, clkdm->clkdm_offs);
- return 0;
-}
-
-static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
-{
- omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
- clkdm->cm_inst, clkdm->clkdm_offs);
- return 0;
-}
-
-static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
-{
- omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst, clkdm->clkdm_offs);
-}
-
-static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
-{
- if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
- omap4_clkdm_wakeup(clkdm);
- else
- omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
-}
-
-static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
-{
- if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
- return omap4_clkdm_wakeup(clkdm);
-
- return 0;
-}
-
-static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
-{
- bool hwsup = false;
-
- if (!clkdm->prcm_partition)
- return 0;
-
- /*
- * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
- * more details on the unpleasant problem this is working
- * around
- */
- if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
- !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
- omap4_clkdm_allow_idle(clkdm);
- return 0;
- }
-
- hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst, clkdm->clkdm_offs);
-
- if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
- omap4_clkdm_sleep(clkdm);
-
- return 0;
-}
-
-struct clkdm_ops omap4_clkdm_operations = {
- .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
- .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
- .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
- .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
- .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
- .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
- .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
- .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
- .clkdm_sleep = omap4_clkdm_sleep,
- .clkdm_wakeup = omap4_clkdm_wakeup,
- .clkdm_allow_idle = omap4_clkdm_allow_idle,
- .clkdm_deny_idle = omap4_clkdm_deny_idle,
- .clkdm_clk_enable = omap4_clkdm_clk_enable,
- .clkdm_clk_disable = omap4_clkdm_clk_disable,
-};
diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h
index 686290437568..11eaf16880c4 100644
--- a/arch/arm/mach-omap2/cm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -333,7 +333,9 @@
#define OMAP24XX_EN_DPLL_MASK (0x3 << 0)
/* CM_IDLEST_CKGEN */
+#define OMAP24XX_ST_54M_APLL_SHIFT 9
#define OMAP24XX_ST_54M_APLL_MASK (1 << 9)
+#define OMAP24XX_ST_96M_APLL_SHIFT 8
#define OMAP24XX_ST_96M_APLL_MASK (1 << 8)
#define OMAP24XX_ST_54M_CLK_MASK (1 << 6)
#define OMAP24XX_ST_12M_CLK_MASK (1 << 5)
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index f24e3f7a2bbc..93473f9a551c 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -1,7 +1,7 @@
/*
* OMAP2+ Clock Management prototypes
*
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation
*
* Written by Paul Walmsley
@@ -22,6 +22,12 @@
*/
#define MAX_MODULE_READY_TIME 2000
+# ifndef __ASSEMBLER__
+extern void __iomem *cm_base;
+extern void __iomem *cm2_base;
+extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
+# endif
+
/*
* MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for
* the PRCM to request that a module enter the inactive state in the
@@ -33,4 +39,26 @@
*/
#define MAX_MODULE_DISABLE_TIME 5000
+# ifndef __ASSEMBLER__
+
+/**
+ * struct cm_ll_data - fn ptrs to per-SoC CM function implementations
+ * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl
+ * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl
+ */
+struct cm_ll_data {
+ int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id);
+ int (*wait_module_ready)(s16 prcm_mod, u8 idlest_id, u8 idlest_shift);
+};
+
+extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id);
+extern int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift);
+
+extern int cm_register(struct cm_ll_data *cld);
+extern int cm_unregister(struct cm_ll_data *cld);
+
+# endif
+
#endif
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
new file mode 100644
index 000000000000..db650690e9d0
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -0,0 +1,381 @@
+/*
+ * OMAP2xxx CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "prm2xxx.h"
+#include "cm.h"
+#include "cm2xxx.h"
+#include "cm-regbits-24xx.h"
+#include "clockdomain.h"
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
+#define DPLL_AUTOIDLE_DISABLE 0x0
+#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
+#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
+#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
+
+/* CM_IDLEST_PLL bit value offset for APLLs (OMAP2xxx only) */
+#define EN_APLL_LOCKED 3
+
+static const u8 omap2xxx_cm_idlest_offs[] = {
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
+};
+
+/*
+ *
+ */
+
+static void _write_clktrctrl(u8 c, s16 module, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= ~mask;
+ v |= c << __ffs(mask);
+ omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
+}
+
+bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+}
+
+void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+/*
+ * DPLL autoidle control
+ */
+
+static void _omap2xxx_set_dpll_autoidle(u8 m)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+ v &= ~OMAP24XX_AUTO_DPLL_MASK;
+ v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_dpll_disable_autoidle(void)
+{
+ _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
+}
+
+void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
+{
+ _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
+}
+
+/*
+ * APLL control
+ */
+
+static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+ v &= ~mask;
+ v |= m << __ffs(mask);
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_apll54_disable_autoidle(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+ OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+ OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_disable_autoidle(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+ OMAP24XX_AUTO_96M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+ OMAP24XX_AUTO_96M_MASK);
+}
+
+/* Enable an APLL if off */
+static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit)
+{
+ u32 v, m;
+
+ m = EN_APLL_LOCKED << enable_bit;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ if (v & m)
+ return 0; /* apll already enabled */
+
+ v |= m;
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
+
+ omap2xxx_cm_wait_module_ready(PLL_MOD, 1, status_bit);
+
+ /*
+ * REVISIT: Should we return an error code if
+ * omap2xxx_cm_wait_module_ready() fails?
+ */
+ return 0;
+}
+
+/* Stop APLL */
+static void _omap2xxx_apll_disable(u8 enable_bit)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ v &= ~(EN_APLL_LOCKED << enable_bit);
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
+}
+
+/* Enable an APLL if off */
+int omap2xxx_cm_apll54_enable(void)
+{
+ return _omap2xxx_apll_enable(OMAP24XX_EN_54M_PLL_SHIFT,
+ OMAP24XX_ST_54M_APLL_SHIFT);
+}
+
+/* Enable an APLL if off */
+int omap2xxx_cm_apll96_enable(void)
+{
+ return _omap2xxx_apll_enable(OMAP24XX_EN_96M_PLL_SHIFT,
+ OMAP24XX_ST_96M_APLL_SHIFT);
+}
+
+/* Stop APLL */
+void omap2xxx_cm_apll54_disable(void)
+{
+ _omap2xxx_apll_disable(OMAP24XX_EN_54M_PLL_SHIFT);
+}
+
+/* Stop APLL */
+void omap2xxx_cm_apll96_disable(void)
+{
+ _omap2xxx_apll_disable(OMAP24XX_EN_96M_PLL_SHIFT);
+}
+
+/**
+ * omap2xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
+ * @idlest_reg: CM_IDLEST* virtual address
+ * @prcm_inst: pointer to an s16 to return the PRCM instance offset
+ * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
+ *
+ * XXX This function is only needed until absolute register addresses are
+ * removed from the OMAP struct clk records.
+ */
+int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id)
+{
+ unsigned long offs;
+ u8 idlest_offs;
+ int i;
+
+ if (idlest_reg < cm_base || idlest_reg > (cm_base + 0x0fff))
+ return -EINVAL;
+
+ idlest_offs = (unsigned long)idlest_reg & 0xff;
+ for (i = 0; i < ARRAY_SIZE(omap2xxx_cm_idlest_offs); i++) {
+ if (idlest_offs == omap2xxx_cm_idlest_offs[i]) {
+ *idlest_reg_id = i + 1;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(omap2xxx_cm_idlest_offs))
+ return -EINVAL;
+
+ offs = idlest_reg - cm_base;
+ offs &= 0xff00;
+ *prcm_inst = offs;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+/**
+ * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
+ * success or -EBUSY if the module doesn't enable in time.
+ */
+int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+ int ena = 0, i = 0;
+ u8 cm_idlest_reg;
+ u32 mask;
+
+ if (!idlest_id || (idlest_id > ARRAY_SIZE(omap2xxx_cm_idlest_offs)))
+ return -EINVAL;
+
+ cm_idlest_reg = omap2xxx_cm_idlest_offs[idlest_id - 1];
+
+ mask = 1 << idlest_shift;
+ ena = mask;
+
+ omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
+ mask) == ena), MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/* Clockdomain low-level functions */
+
+static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
+
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
+
+static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ _clkdm_add_autodeps(clkdm);
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ } else {
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap2xxx_clkdm_wakeup(clkdm);
+ }
+
+ return 0;
+}
+
+static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ _clkdm_del_autodeps(clkdm);
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ } else {
+ if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+ omap2xxx_clkdm_sleep(clkdm);
+ }
+
+ return 0;
+}
+
+struct clkdm_ops omap2_clkdm_operations = {
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
+ .clkdm_sleep = omap2xxx_clkdm_sleep,
+ .clkdm_wakeup = omap2xxx_clkdm_wakeup,
+ .clkdm_allow_idle = omap2xxx_clkdm_allow_idle,
+ .clkdm_deny_idle = omap2xxx_clkdm_deny_idle,
+ .clkdm_clk_enable = omap2xxx_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2xxx_clkdm_clk_disable,
+};
+
+/*
+ *
+ */
+
+static struct cm_ll_data omap2xxx_cm_ll_data = {
+ .split_idlest_reg = &omap2xxx_cm_split_idlest_reg,
+ .wait_module_ready = &omap2xxx_cm_wait_module_ready,
+};
+
+int __init omap2xxx_cm_init(void)
+{
+ if (!cpu_is_omap24xx())
+ return 0;
+
+ return cm_register(&omap2xxx_cm_ll_data);
+}
+
+static void __exit omap2xxx_cm_exit(void)
+{
+ if (!cpu_is_omap24xx())
+ return;
+
+ /* Should never happen */
+ WARN(cm_unregister(&omap2xxx_cm_ll_data),
+ "%s: cm_ll_data function pointer mismatch\n", __func__);
+}
+__exitcall(omap2xxx_cm_exit);
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
new file mode 100644
index 000000000000..4cbb39b051d2
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -0,0 +1,70 @@
+/*
+ * OMAP2xxx Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * The CM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The CM modules/instances on OMAP4 are quite different, so
+ * they are handled in a separate file.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM2XXX_H
+
+#include "prcm-common.h"
+#include "cm2xxx_3xxx.h"
+
+#define OMAP2420_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
+#define OMAP2430_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
+
+/*
+ * Module specific CM register offsets from CM_BASE + domain offset
+ * Use cm_{read,write}_mod_reg() with these registers.
+ * These register offsets generally appear in more than one PRCM submodule.
+ */
+
+/* OMAP2-specific register offsets */
+
+#define OMAP24XX_CM_FCLKEN2 0x0004
+#define OMAP24XX_CM_ICLKEN4 0x001c
+#define OMAP24XX_CM_AUTOIDLE4 0x003c
+#define OMAP24XX_CM_IDLEST4 0x002c
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP24XX_CM_IDLEST_VAL 0
+
+
+/* Clock management domain register get/set */
+
+#ifndef __ASSEMBLER__
+
+extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+
+extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
+extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
+
+extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
+extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
+
+extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
+extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+ u8 idlest_shift);
+extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
+ s16 *prcm_inst, u8 *idlest_reg_id);
+
+extern int __init omap2xxx_cm_init(void);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 57b2f3c2fbf3..98e6b3c9cd9b 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -16,28 +16,7 @@
#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
#define __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
-#include "prcm-common.h"
-
-#define OMAP2420_CM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
-#define OMAP2430_CM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
-#define OMAP34XX_CM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
-
-
-/*
- * OMAP3-specific global CM registers
- * Use cm_{read,write}_reg() with these registers.
- * These registers appear once per CM module.
- */
-
-#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
-#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
-
-#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
-#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+#include "cm.h"
/*
* Module specific CM register offsets from CM_BASE + domain offset
@@ -57,6 +36,7 @@
#define CM_IDLEST 0x0020
#define CM_IDLEST1 CM_IDLEST
#define CM_IDLEST2 0x0024
+#define OMAP2430_CM_IDLEST3 0x0028
#define CM_AUTOIDLE 0x0030
#define CM_AUTOIDLE1 CM_AUTOIDLE
#define CM_AUTOIDLE2 0x0034
@@ -66,70 +46,60 @@
#define CM_CLKSEL2 0x0044
#define OMAP2_CM_CLKSTCTRL 0x0048
-/* OMAP2-specific register offsets */
-
-#define OMAP24XX_CM_FCLKEN2 0x0004
-#define OMAP24XX_CM_ICLKEN4 0x001c
-#define OMAP24XX_CM_AUTOIDLE4 0x003c
-#define OMAP24XX_CM_IDLEST4 0x002c
-
-#define OMAP2430_CM_IDLEST3 0x0028
-
-/* OMAP3-specific register offsets */
-
-#define OMAP3430_CM_CLKEN_PLL 0x0004
-#define OMAP3430ES2_CM_CLKEN2 0x0004
-#define OMAP3430ES2_CM_FCLKEN3 0x0008
-#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
-#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
-#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
-#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
-#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
-#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
-#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
-#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
-#define OMAP3430_CM_CLKSTST 0x004c
-#define OMAP3430ES2_CM_CLKSEL4 0x004c
-#define OMAP3430ES2_CM_CLKSEL5 0x0050
-#define OMAP3430_CM_CLKSEL2_EMU 0x0050
-#define OMAP3430_CM_CLKSEL3_EMU 0x0054
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
-/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
+{
+ return __raw_readl(cm_base + module + idx);
+}
-#define OMAP24XX_CM_IDLEST_VAL 0
-#define OMAP34XX_CM_IDLEST_VAL 1
+static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __raw_writel(val, cm_base + module + idx);
+}
+/* Read-modify-write a register in a CM module. Caller must lock */
+static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
+ s16 idx)
+{
+ u32 v;
-/* Clock management domain register get/set */
+ v = omap2_cm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ omap2_cm_write_mod_reg(v, module, idx);
-#ifndef __ASSEMBLER__
+ return v;
+}
-extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx);
-extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx);
-extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+/* Read a CM register, AND it, and shift the result down to bit 0 */
+static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ u32 v;
-extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
- u8 idlest_shift);
-extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
-extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
+ v = omap2_cm_read_mod_reg(domain, idx);
+ v &= mask;
+ v >>= __ffs(mask);
-extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
-extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
-extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+ return v;
+}
-extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
-extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
-extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
-extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
+static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
-extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
-extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
+static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
-extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
-extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
-extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
-extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
+extern int omap2xxx_cm_apll54_enable(void);
+extern void omap2xxx_cm_apll54_disable(void);
+extern int omap2xxx_cm_apll96_enable(void);
+extern void omap2xxx_cm_apll96_disable(void);
#endif
@@ -146,11 +116,4 @@ extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
/* CM_IDLEST_GFX */
#define OMAP_ST_GFX_MASK (1 << 0)
-
-/* Function prototypes */
-# ifndef __ASSEMBLER__
-extern void omap3_cm_save_context(void);
-extern void omap3_cm_restore_context(void);
-# endif
-
#endif
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index ed8dcaf4c849..058ce3c0873e 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -22,6 +22,7 @@
#include <linux/err.h>
#include <linux/io.h>
+#include "clockdomain.h"
#include "cm.h"
#include "cm33xx.h"
#include "cm-regbits-34xx.h"
@@ -309,3 +310,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)
v &= ~AM33XX_MODULEMODE_MASK;
am33xx_cm_write_reg(v, inst, clkctrl_offs);
}
+
+/*
+ * Clockdomain low-level functions
+ */
+
+static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ return am33xx_clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+ am33xx_clkdm_sleep(clkdm);
+
+ return 0;
+}
+
+struct clkdm_ops am33xx_clkdm_operations = {
+ .clkdm_sleep = am33xx_clkdm_sleep,
+ .clkdm_wakeup = am33xx_clkdm_wakeup,
+ .clkdm_allow_idle = am33xx_clkdm_allow_idle,
+ .clkdm_deny_idle = am33xx_clkdm_deny_idle,
+ .clkdm_clk_enable = am33xx_clkdm_clk_enable,
+ .clkdm_clk_disable = am33xx_clkdm_clk_disable,
+};
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 7f07ab02a5b3..c2086f2e86b6 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -1,8 +1,10 @@
/*
- * OMAP2/3 CM module functions
+ * OMAP3xxx CM module functions
*
* Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
* Paul Walmsley
+ * 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
@@ -12,8 +14,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -21,56 +21,16 @@
#include "soc.h"
#include "iomap.h"
#include "common.h"
+#include "prm2xxx_3xxx.h"
#include "cm.h"
-#include "cm2xxx_3xxx.h"
-#include "cm-regbits-24xx.h"
+#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
+#include "clockdomain.h"
-/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
-#define DPLL_AUTOIDLE_DISABLE 0x0
-#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
-
-/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
-#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
-#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
-
-static const u8 cm_idlest_offs[] = {
- CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
+static const u8 omap3xxx_cm_idlest_offs[] = {
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
};
-u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
-{
- return __raw_readl(cm_base + module + idx);
-}
-
-void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
-{
- __raw_writel(val, cm_base + module + idx);
-}
-
-/* Read-modify-write a register in a CM module. Caller must lock */
-u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
-{
- u32 v;
-
- v = omap2_cm_read_mod_reg(module, idx);
- v &= ~mask;
- v |= bits;
- omap2_cm_write_mod_reg(v, module, idx);
-
- return v;
-}
-
-u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
-}
-
-u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
-}
-
/*
*
*/
@@ -85,33 +45,15 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask)
omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
}
-bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
{
u32 v;
- bool ret = 0;
-
- BUG_ON(!cpu_is_omap24xx() && !cpu_is_omap34xx());
v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
v &= mask;
v >>= __ffs(mask);
- if (cpu_is_omap24xx())
- ret = (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
- else
- ret = (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
-
- return ret;
-}
-
-void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
-{
- _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
-}
-
-void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
-{
- _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+ return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
}
void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
@@ -135,109 +77,247 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
}
/*
- * DPLL autoidle control
+ *
*/
-static void _omap2xxx_set_dpll_autoidle(u8 m)
+/**
+ * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
+ * success or -EBUSY if the module doesn't enable in time.
+ */
+int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
{
- u32 v;
+ int ena = 0, i = 0;
+ u8 cm_idlest_reg;
+ u32 mask;
- v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
- v &= ~OMAP24XX_AUTO_DPLL_MASK;
- v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
- omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
-}
+ if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
+ return -EINVAL;
-void omap2xxx_cm_set_dpll_disable_autoidle(void)
-{
- _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
+ cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
+
+ mask = 1 << idlest_shift;
+ ena = 0;
+
+ omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
+ mask) == ena), MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}
-void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
+/**
+ * omap3xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
+ * @idlest_reg: CM_IDLEST* virtual address
+ * @prcm_inst: pointer to an s16 to return the PRCM instance offset
+ * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
+ *
+ * XXX This function is only needed until absolute register addresses are
+ * removed from the OMAP struct clk records.
+ */
+int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id)
{
- _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
+ unsigned long offs;
+ u8 idlest_offs;
+ int i;
+
+ if (idlest_reg < (cm_base + OMAP3430_IVA2_MOD) ||
+ idlest_reg > (cm_base + 0x1ffff))
+ return -EINVAL;
+
+ idlest_offs = (unsigned long)idlest_reg & 0xff;
+ for (i = 0; i < ARRAY_SIZE(omap3xxx_cm_idlest_offs); i++) {
+ if (idlest_offs == omap3xxx_cm_idlest_offs[i]) {
+ *idlest_reg_id = i + 1;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(omap3xxx_cm_idlest_offs))
+ return -EINVAL;
+
+ offs = idlest_reg - cm_base;
+ offs &= 0xff00;
+ *prcm_inst = offs;
+
+ return 0;
}
-/*
- * APLL autoidle control
- */
+/* Clockdomain low-level operations */
-static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
+static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
{
- u32 v;
+ omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
+}
- v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
- v &= ~mask;
- v |= m << __ffs(mask);
- omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
}
-void omap2xxx_cm_set_apll54_disable_autoidle(void)
+static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
{
- _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
- OMAP24XX_AUTO_54M_MASK);
+ return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP,
+ (1 << clkdm2->dep_bit));
}
-void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
+static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
{
- _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
- OMAP24XX_AUTO_54M_MASK);
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->sleepdep_usecount, 0);
+ }
+ omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
}
-void omap2xxx_cm_set_apll96_disable_autoidle(void)
+static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
{
- _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
- OMAP24XX_AUTO_96M_MASK);
+ omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
}
-void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
+static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
{
- _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
- OMAP24XX_AUTO_96M_MASK);
+ omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
}
-/*
- *
- */
+static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
-/**
- * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
- * @prcm_mod: PRCM module offset
- * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
- * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
- *
- * XXX document
- */
-int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
{
- int ena = 0, i = 0;
- u8 cm_idlest_reg;
- u32 mask;
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
- if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
- return -EINVAL;
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
- cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
+static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
- mask = 1 << idlest_shift;
+ if (!clkdm->clktrctrl_mask)
+ return 0;
- if (cpu_is_omap24xx())
- ena = mask;
- else if (cpu_is_omap34xx())
- ena = 0;
- else
- BUG();
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+ (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+ omap3xxx_clkdm_wakeup(clkdm);
+ return 0;
+ }
+
+ hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ _clkdm_add_autodeps(clkdm);
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ } else {
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap3xxx_clkdm_wakeup(clkdm);
+ }
+
+ return 0;
+}
- omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
- MAX_MODULE_READY_TIME, i);
+static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
- return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+ }
+
+ hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ _clkdm_del_autodeps(clkdm);
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ } else {
+ if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+ omap3xxx_clkdm_sleep(clkdm);
+ }
+
+ return 0;
}
+struct clkdm_ops omap3_clkdm_operations = {
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
+ .clkdm_add_sleepdep = omap3xxx_clkdm_add_sleepdep,
+ .clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep,
+ .clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep,
+ .clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps,
+ .clkdm_sleep = omap3xxx_clkdm_sleep,
+ .clkdm_wakeup = omap3xxx_clkdm_wakeup,
+ .clkdm_allow_idle = omap3xxx_clkdm_allow_idle,
+ .clkdm_deny_idle = omap3xxx_clkdm_deny_idle,
+ .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
+ .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
+};
+
/*
* Context save/restore code - OMAP3 only
*/
-#ifdef CONFIG_ARCH_OMAP3
struct omap3_cm_regs {
u32 iva2_cm_clksel1;
u32 iva2_cm_clksel2;
@@ -555,4 +635,31 @@ void omap3_cm_restore_context(void)
omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
OMAP3_CM_CLKOUT_CTRL_OFFSET);
}
-#endif
+
+/*
+ *
+ */
+
+static struct cm_ll_data omap3xxx_cm_ll_data = {
+ .split_idlest_reg = &omap3xxx_cm_split_idlest_reg,
+ .wait_module_ready = &omap3xxx_cm_wait_module_ready,
+};
+
+int __init omap3xxx_cm_init(void)
+{
+ if (!cpu_is_omap34xx())
+ return 0;
+
+ return cm_register(&omap3xxx_cm_ll_data);
+}
+
+static void __exit omap3xxx_cm_exit(void)
+{
+ if (!cpu_is_omap34xx())
+ return;
+
+ /* Should never happen */
+ WARN(cm_unregister(&omap3xxx_cm_ll_data),
+ "%s: cm_ll_data function pointer mismatch\n", __func__);
+}
+__exitcall(omap3xxx_cm_exit);
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h
new file mode 100644
index 000000000000..e8e146f4a43f
--- /dev/null
+++ b/arch/arm/mach-omap2/cm3xxx.h
@@ -0,0 +1,91 @@
+/*
+ * OMAP2/3 Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * The CM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The CM modules/instances on OMAP4 are quite different, so
+ * they are handled in a separate file.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM3XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM3XXX_H
+
+#include "prcm-common.h"
+#include "cm2xxx_3xxx.h"
+
+#define OMAP34XX_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP3-specific global CM registers
+ * Use cm_{read,write}_reg() with these registers.
+ * These registers appear once per CM module.
+ */
+
+#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
+#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
+
+#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/*
+ * Module specific CM register offsets from CM_BASE + domain offset
+ * Use cm_{read,write}_mod_reg() with these registers.
+ * These register offsets generally appear in more than one PRCM submodule.
+ */
+
+/* OMAP3-specific register offsets */
+
+#define OMAP3430_CM_CLKEN_PLL 0x0004
+#define OMAP3430ES2_CM_CLKEN2 0x0004
+#define OMAP3430ES2_CM_FCLKEN3 0x0008
+#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
+#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
+#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
+#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
+#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
+#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
+#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
+#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
+#define OMAP3430_CM_CLKSTST 0x004c
+#define OMAP3430ES2_CM_CLKSEL4 0x004c
+#define OMAP3430ES2_CM_CLKSEL5 0x0050
+#define OMAP3430_CM_CLKSEL2_EMU 0x0050
+#define OMAP3430_CM_CLKSEL3_EMU 0x0054
+
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP34XX_CM_IDLEST_VAL 1
+
+
+#ifndef __ASSEMBLER__
+
+extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
+
+extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
+extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+ u8 idlest_shift);
+
+extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
+ s16 *prcm_inst, u8 *idlest_reg_id);
+
+extern void omap3_cm_save_context(void);
+extern void omap3_cm_restore_context(void);
+
+extern int __init omap3xxx_cm_init(void);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
new file mode 100644
index 000000000000..40b3b5a84458
--- /dev/null
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -0,0 +1,140 @@
+/*
+ * OMAP2+ common Clock Management (CM) IP block functions
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * XXX This code should eventually be moved to a CM driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include "cm2xxx.h"
+#include "cm3xxx.h"
+#include "cm44xx.h"
+#include "common.h"
+
+/*
+ * cm_ll_data: function pointers to SoC-specific implementations of
+ * common CM functions
+ */
+static struct cm_ll_data null_cm_ll_data;
+static struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
+
+/* cm_base: base virtual address of the CM IP block */
+void __iomem *cm_base;
+
+/* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */
+void __iomem *cm2_base;
+
+/**
+ * omap2_set_globals_cm - set the CM/CM2 base addresses (for early use)
+ * @cm: CM base virtual address
+ * @cm2: CM2 base virtual address (if present on the booted SoC)
+ *
+ * XXX Will be replaced when the PRM/CM drivers are completed.
+ */
+void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2)
+{
+ cm_base = cm;
+ cm2_base = cm2;
+}
+
+/**
+ * cm_split_idlest_reg - split CM_IDLEST reg addr into its components
+ * @idlest_reg: CM_IDLEST* virtual address
+ * @prcm_inst: pointer to an s16 to return the PRCM instance offset
+ * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
+ *
+ * Given an absolute CM_IDLEST register address @idlest_reg, passes
+ * the PRCM instance offset and IDLEST register ID back to the caller
+ * via the @prcm_inst and @idlest_reg_id. Returns -EINVAL upon error,
+ * or 0 upon success. XXX This function is only needed until absolute
+ * register addresses are removed from the OMAP struct clk records.
+ */
+int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id)
+{
+ if (!cm_ll_data->split_idlest_reg) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return cm_ll_data->split_idlest_reg(idlest_reg, prcm_inst,
+ idlest_reg_id);
+}
+
+/**
+ * cm_wait_module_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
+ * success, -EBUSY if the module doesn't enable in time, or -EINVAL if
+ * no per-SoC wait_module_ready() function pointer has been registered
+ * or if the idlest register is unknown on the SoC.
+ */
+int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+ if (!cm_ll_data->wait_module_ready) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return cm_ll_data->wait_module_ready(prcm_mod, idlest_id, idlest_shift);
+}
+
+/**
+ * cm_register - register per-SoC low-level data with the CM
+ * @cld: low-level per-SoC OMAP CM data & function pointers to register
+ *
+ * Register per-SoC low-level OMAP CM data and function pointers with
+ * the OMAP CM common interface. The caller must keep the data
+ * pointed to by @cld valid until it calls cm_unregister() and
+ * it returns successfully. Returns 0 upon success, -EINVAL if @cld
+ * is NULL, or -EEXIST if cm_register() has already been called
+ * without an intervening cm_unregister().
+ */
+int cm_register(struct cm_ll_data *cld)
+{
+ if (!cld)
+ return -EINVAL;
+
+ if (cm_ll_data != &null_cm_ll_data)
+ return -EEXIST;
+
+ cm_ll_data = cld;
+
+ return 0;
+}
+
+/**
+ * cm_unregister - unregister per-SoC low-level data & function pointers
+ * @cld: low-level per-SoC OMAP CM data & function pointers to unregister
+ *
+ * Unregister per-SoC low-level OMAP CM data and function pointers
+ * that were previously registered with cm_register(). The
+ * caller may not destroy any of the data pointed to by @cld until
+ * this function returns successfully. Returns 0 upon success, or
+ * -EINVAL if @cld is NULL or if @cld does not match the struct
+ * cm_ll_data * previously registered by cm_register().
+ */
+int cm_unregister(struct cm_ll_data *cld)
+{
+ if (!cld || cm_ll_data != cld)
+ return -EINVAL;
+
+ cm_ll_data = &null_cm_ll_data;
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 1894015ff04b..7f9a464f01e9 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -2,8 +2,9 @@
* OMAP4 CM instance functions
*
* Copyright (C) 2009 Nokia Corporation
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
* Paul Walmsley
+ * 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
@@ -22,6 +23,7 @@
#include "iomap.h"
#include "common.h"
+#include "clockdomain.h"
#include "cm.h"
#include "cm1_44xx.h"
#include "cm2_44xx.h"
@@ -343,3 +345,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
v &= ~OMAP4430_MODULEMODE_MASK;
omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
}
+
+/*
+ * Clockdomain low-level functions
+ */
+
+static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->prcm_partition,
+ clkdm1->cm_inst, clkdm1->clkdm_offs +
+ OMAP4_CM_STATICDEP);
+ return 0;
+}
+
+static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->prcm_partition,
+ clkdm1->cm_inst, clkdm1->clkdm_offs +
+ OMAP4_CM_STATICDEP);
+ return 0;
+}
+
+static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
+ clkdm1->cm_inst,
+ clkdm1->clkdm_offs +
+ OMAP4_CM_STATICDEP,
+ (1 << clkdm2->dep_bit));
+}
+
+static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
+{
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ if (!clkdm->prcm_partition)
+ return 0;
+
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->wkdep_usecount, 0);
+ }
+
+ omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs +
+ OMAP4_CM_STATICDEP);
+ return 0;
+}
+
+static int omap4_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap4_clkdm_wakeup(clkdm);
+ else
+ omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+}
+
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ return omap4_clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->prcm_partition)
+ return 0;
+
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ omap4_clkdm_allow_idle(clkdm);
+ return 0;
+ }
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+ omap4_clkdm_sleep(clkdm);
+
+ return 0;
+}
+
+struct clkdm_ops omap4_clkdm_operations = {
+ .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
+ .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
+ .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
+ .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
+ .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
+ .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
+ .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
+ .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
+ .clkdm_sleep = omap4_clkdm_sleep,
+ .clkdm_wakeup = omap4_clkdm_wakeup,
+ .clkdm_allow_idle = omap4_clkdm_allow_idle,
+ .clkdm_deny_idle = omap4_clkdm_deny_idle,
+ .clkdm_clk_enable = omap4_clkdm_clk_enable,
+ .clkdm_clk_disable = omap4_clkdm_clk_disable,
+};
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
index d69fdefef985..bd7bab889745 100644
--- a/arch/arm/mach-omap2/cminst44xx.h
+++ b/arch/arm/mach-omap2/cminst44xx.h
@@ -38,4 +38,6 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
u32 mask);
+extern void omap_cm_base_init(void);
+
#endif
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
index 34fb5b95859b..5c2fd4863b2b 100644
--- a/arch/arm/mach-omap2/common.c
+++ b/arch/arm/mach-omap2/common.c
@@ -14,196 +14,13 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
#include <linux/platform_data/dsp-omap.h>
#include <plat/vram.h>
-#include "soc.h"
-#include "iomap.h"
#include "common.h"
-#include "clock.h"
-#include "sdrc.h"
-#include "control.h"
#include "omap-secure.h"
-/* Global address base setup code */
-
-static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
-{
- omap2_set_globals_tap(omap2_globals);
- omap2_set_globals_sdrc(omap2_globals);
- omap2_set_globals_control(omap2_globals);
- omap2_set_globals_prcm(omap2_globals);
-}
-
-#if defined(CONFIG_SOC_OMAP2420)
-
-static struct omap_globals omap242x_globals = {
- .class = OMAP242X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(0x48014000),
- .sdrc = OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
- .sms = OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE),
- .ctrl = OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE),
- .prm = OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE),
- .cm = OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE),
-};
-
-void __init omap2_set_globals_242x(void)
-{
- __omap2_set_globals(&omap242x_globals);
-}
-
-void __init omap242x_map_io(void)
-{
- omap242x_map_common_io();
-}
-#endif
-
-#if defined(CONFIG_SOC_OMAP2430)
-
-static struct omap_globals omap243x_globals = {
- .class = OMAP243X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(0x4900a000),
- .sdrc = OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
- .sms = OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE),
- .ctrl = OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE),
- .prm = OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE),
- .cm = OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE),
-};
-
-void __init omap2_set_globals_243x(void)
-{
- __omap2_set_globals(&omap243x_globals);
-}
-
-void __init omap243x_map_io(void)
-{
- omap243x_map_common_io();
-}
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3)
-
-static struct omap_globals omap3_globals = {
- .class = OMAP343X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(0x4830A000),
- .sdrc = OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
- .sms = OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE),
- .ctrl = OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE),
- .prm = OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE),
- .cm = OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE),
-};
-
-void __init omap2_set_globals_3xxx(void)
-{
- __omap2_set_globals(&omap3_globals);
-}
-
-void __init omap3_map_io(void)
-{
- omap34xx_map_common_io();
-}
-
-/*
- * Adjust TAP register base such that omap3_check_revision accesses the correct
- * TI81XX register for checking device ID (it adds 0x204 to tap base while
- * TI81XX DEVICE ID register is at offset 0x600 from control base).
- */
-#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \
- TI81XX_CONTROL_DEVICE_ID - 0x204)
-
-static struct omap_globals ti81xx_globals = {
- .class = OMAP343X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE),
- .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
- .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
- .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
-};
-
-void __init omap2_set_globals_ti81xx(void)
-{
- __omap2_set_globals(&ti81xx_globals);
-}
-
-void __init ti81xx_map_io(void)
-{
- omapti81xx_map_common_io();
-}
-#endif
-
-#if defined(CONFIG_SOC_AM33XX)
-#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \
- TI81XX_CONTROL_DEVICE_ID - 0x204)
-
-static struct omap_globals am33xx_globals = {
- .class = AM335X_CLASS,
- .tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE),
- .ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
- .prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
- .cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
-};
-
-void __init omap2_set_globals_am33xx(void)
-{
- __omap2_set_globals(&am33xx_globals);
-}
-
-void __init am33xx_map_io(void)
-{
- omapam33xx_map_common_io();
-}
-#endif
-
-#if defined(CONFIG_ARCH_OMAP4)
-static struct omap_globals omap4_globals = {
- .class = OMAP443X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
- .ctrl = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
- .ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE),
- .prm = OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE),
- .cm = OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
- .cm2 = OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE),
- .prcm_mpu = OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE),
-};
-
-void __init omap2_set_globals_443x(void)
-{
- __omap2_set_globals(&omap4_globals);
-}
-
-void __init omap4_map_io(void)
-{
- omap44xx_map_common_io();
-}
-#endif
-
-#if defined(CONFIG_SOC_OMAP5)
-static struct omap_globals omap5_globals = {
- .class = OMAP54XX_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE),
- .ctrl = OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE),
- .ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE),
- .prm = OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE),
- .cm = OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
- .cm2 = OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE),
- .prcm_mpu = OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE),
-};
-
-void __init omap2_set_globals_5xxx(void)
-{
- omap2_set_globals_tap(&omap5_globals);
- omap2_set_globals_control(&omap5_globals);
- omap2_set_globals_prcm(&omap5_globals);
-}
-
-void __init omap5_map_io(void)
-{
- omap5_map_common_io();
-}
-#endif
-
/*
* Stub function for OMAP2 so that common files
* continue to build when custom builds are used
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 426fcfcfd821..08c586451f93 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -41,54 +41,6 @@
#define OMAP_INTC_START NR_IRQS
-#ifdef CONFIG_SOC_OMAP2420
-extern void omap242x_map_common_io(void);
-#else
-static inline void omap242x_map_common_io(void)
-{
-}
-#endif
-
-#ifdef CONFIG_SOC_OMAP2430
-extern void omap243x_map_common_io(void);
-#else
-static inline void omap243x_map_common_io(void)
-{
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-extern void omap34xx_map_common_io(void);
-#else
-static inline void omap34xx_map_common_io(void)
-{
-}
-#endif
-
-#ifdef CONFIG_SOC_TI81XX
-extern void omapti81xx_map_common_io(void);
-#else
-static inline void omapti81xx_map_common_io(void)
-{
-}
-#endif
-
-#ifdef CONFIG_SOC_AM33XX
-extern void omapam33xx_map_common_io(void);
-#else
-static inline void omapam33xx_map_common_io(void)
-{
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-extern void omap44xx_map_common_io(void);
-#else
-static inline void omap44xx_map_common_io(void)
-{
-}
-#endif
-
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
int omap2_pm_init(void);
#else
@@ -125,14 +77,6 @@ static inline int omap_mux_late_init(void)
}
#endif
-#ifdef CONFIG_SOC_OMAP5
-extern void omap5_map_common_io(void);
-#else
-static inline void omap5_map_common_io(void)
-{
-}
-#endif
-
extern void omap2_init_common_infrastructure(void);
extern struct sys_timer omap2_timer;
@@ -165,52 +109,43 @@ void am35xx_init_late(void);
void ti81xx_init_late(void);
void omap4430_init_late(void);
int omap2_common_pm_late_init(void);
-void omap_prcm_restart(char, const char *);
-/*
- * IO bases for various OMAP processors
- * Except the tap base, rest all the io bases
- * listed are physical addresses.
- */
-struct omap_globals {
- u32 class; /* OMAP class to detect */
- void __iomem *tap; /* Control module ID code */
- void __iomem *sdrc; /* SDRAM Controller */
- void __iomem *sms; /* SDRAM Memory Scheduler */
- void __iomem *ctrl; /* System Control Module */
- void __iomem *ctrl_pad; /* PAD Control Module */
- void __iomem *prm; /* Power and Reset Management */
- void __iomem *cm; /* Clock Management */
- void __iomem *cm2;
- void __iomem *prcm_mpu;
-};
-
-void omap2_set_globals_242x(void);
-void omap2_set_globals_243x(void);
-void omap2_set_globals_3xxx(void);
-void omap2_set_globals_443x(void);
-void omap2_set_globals_5xxx(void);
-void omap2_set_globals_ti81xx(void);
-void omap2_set_globals_am33xx(void);
-
-/* These get called from omap2_set_globals_xxxx(), do not call these */
-void omap2_set_globals_tap(struct omap_globals *);
-#if defined(CONFIG_SOC_HAS_OMAP2_SDRC)
-void omap2_set_globals_sdrc(struct omap_globals *);
+#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
+void omap2xxx_restart(char mode, const char *cmd);
#else
-static inline void omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
-{ }
+static inline void omap2xxx_restart(char mode, const char *cmd)
+{
+}
#endif
-void omap2_set_globals_control(struct omap_globals *);
-void omap2_set_globals_prcm(struct omap_globals *);
-
-void omap242x_map_io(void);
-void omap243x_map_io(void);
-void omap3_map_io(void);
-void am33xx_map_io(void);
-void omap4_map_io(void);
-void omap5_map_io(void);
-void ti81xx_map_io(void);
+
+#ifdef CONFIG_ARCH_OMAP3
+void omap3xxx_restart(char mode, const char *cmd);
+#else
+static inline void omap3xxx_restart(char mode, const char *cmd)
+{
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+void omap44xx_restart(char mode, const char *cmd);
+#else
+static inline void omap44xx_restart(char mode, const char *cmd)
+{
+}
+#endif
+
+/* This gets called from mach-omap2/io.c, do not call this */
+void __init omap2_set_globals_tap(u32 class, void __iomem *tap);
+
+void __init omap242x_map_io(void);
+void __init omap243x_map_io(void);
+void __init omap3_map_io(void);
+void __init am33xx_map_io(void);
+void __init omap4_map_io(void);
+void __init omap5_map_io(void);
+void __init ti81xx_map_io(void);
+
+/* omap_barriers_init() is OMAP4 only */
void omap_barriers_init(void);
/**
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index bf2be5c5468d..2adb2683f074 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -20,8 +20,8 @@
#include "common.h"
#include "cm-regbits-34xx.h"
#include "prm-regbits-34xx.h"
-#include "prm2xxx_3xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "prm3xxx.h"
+#include "cm3xxx.h"
#include "sdrc.h"
#include "pm.h"
#include "control.h"
@@ -147,13 +147,11 @@ 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))
-void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
+void __init omap2_set_globals_control(void __iomem *ctrl,
+ void __iomem *ctrl_pad)
{
- if (omap2_globals->ctrl)
- omap2_ctrl_base = omap2_globals->ctrl;
-
- if (omap2_globals->ctrl_pad)
- omap4_ctrl_pad_base = omap2_globals->ctrl_pad;
+ omap2_ctrl_base = ctrl;
+ omap4_ctrl_pad_base = ctrl_pad;
}
void __iomem *omap_ctrl_base_get(void)
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a89e8256fd0e..4ca8747b3cc9 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -414,6 +414,8 @@ extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr);
extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
extern void omap3630_ctrl_disable_rta(void);
extern int omap3_ctrl_save_padconf(void);
+extern void omap2_set_globals_control(void __iomem *ctrl,
+ void __iomem *ctrl_pad);
#else
#define omap_ctrl_base_get() 0
#define omap_ctrl_readb(x) 0
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index bc2756959be5..bca7a8885703 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -27,7 +27,6 @@
#include <linux/export.h>
#include <linux/cpu_pm.h>
-#include <plat/prcm.h>
#include "powerdomain.h"
#include "clockdomain.h"
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2ad491d6910b..cf365c387c06 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -646,29 +646,3 @@ static int __init omap2_init_devices(void)
return 0;
}
arch_initcall(omap2_init_devices);
-
-#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
-static int __init omap_init_wdt(void)
-{
- int id = -1;
- struct platform_device *pdev;
- struct omap_hwmod *oh;
- char *oh_name = "wd_timer2";
- char *dev_name = "omap_wdt";
-
- if (!cpu_class_is_omap2() || of_have_populated_dt())
- return 0;
-
- oh = omap_hwmod_lookup(oh_name);
- if (!oh) {
- pr_err("Could not look up wd_timer%d hwmod\n", id);
- return -EINVAL;
- }
-
- pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
- WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
- dev_name, oh->name);
- return 0;
-}
-subsys_initcall(omap_init_wdt);
-#endif
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 89c57129357a..38ba58c97628 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -35,6 +35,7 @@
#include "mux.h"
#include "control.h"
#include "display.h"
+#include "prm.h"
#define DISPC_CONTROL 0x0040
#define DISPC_CONTROL2 0x0238
@@ -512,7 +513,6 @@ static void dispc_disable_outputs(void)
}
}
-#define MAX_MODULE_SOFTRESET_WAIT 10000
int omap_dss_reset(struct omap_hwmod *oh)
{
struct omap_hwmod_opt_clk *oc;
diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c
index 3da8900598c8..ab7bf181a105 100644
--- a/arch/arm/mach-omap2/hdq1w.c
+++ b/arch/arm/mach-omap2/hdq1w.c
@@ -31,11 +31,9 @@
#include "omap_device.h"
#include "hdq1w.h"
+#include "prm.h"
#include "common.h"
-/* Maximum microseconds to wait for OMAP module to softreset */
-#define MAX_MODULE_SOFTRESET_WAIT 10000
-
/**
* omap_hdq1w_reset - reset the OMAP HDQ1W module
* @oh: struct omap_hwmod *
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
index 4e63097e3cd8..fbb9b152cd5e 100644
--- a/arch/arm/mach-omap2/i2c.c
+++ b/arch/arm/mach-omap2/i2c.c
@@ -20,10 +20,11 @@
*/
#include "soc.h"
-#include "common.h"
#include "omap_hwmod.h"
#include "omap_device.h"
+#include "prm.h"
+#include "common.h"
#include "mux.h"
#include "i2c.h"
@@ -32,9 +33,6 @@
#define OMAP2_I2C_CON_OFFSET 0x24
#define OMAP4_I2C_CON_OFFSET 0xA4
-/* Maximum microseconds to wait for OMAP module to softreset */
-#define MAX_MODULE_SOFTRESET_WAIT 10000
-
#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
static void __init omap2_i2c_mux_pins(int bus_id)
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index cf2362ccb234..f1e121502789 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -559,11 +559,12 @@ void __init omap5xxx_check_revision(void)
* detect the exact revision later on in omap2_detect_revision() once map_io
* is done.
*/
-void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
+void __init omap2_set_globals_tap(u32 class, void __iomem *tap)
{
- omap_revision = omap2_globals->class;
- tap_base = omap2_globals->tap;
+ omap_revision = class;
+ tap_base = tap;
+ /* XXX What is this intended to do? */
if (cpu_is_omap34xx())
tap_prod_id = 0x0210;
else
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 807b8d919f81..9df757644cce 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -40,8 +40,16 @@
#include "clock44xx.h"
#include "omap-pm.h"
#include "sdrc.h"
+#include "control.h"
#include "serial.h"
#include "sram.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
+#include "prm.h"
+#include "cm.h"
+#include "prcm_mpu44xx.h"
+#include "prminst44xx.h"
+#include "cminst44xx.h"
/*
* The machine specific code may provide the extra mapping besides the
@@ -264,7 +272,7 @@ static struct map_desc omap54xx_io_desc[] __initdata = {
#endif
#ifdef CONFIG_SOC_OMAP2420
-void __init omap242x_map_common_io(void)
+void __init omap242x_map_io(void)
{
iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
@@ -272,7 +280,7 @@ void __init omap242x_map_common_io(void)
#endif
#ifdef CONFIG_SOC_OMAP2430
-void __init omap243x_map_common_io(void)
+void __init omap243x_map_io(void)
{
iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
@@ -280,28 +288,28 @@ void __init omap243x_map_common_io(void)
#endif
#ifdef CONFIG_ARCH_OMAP3
-void __init omap34xx_map_common_io(void)
+void __init omap3_map_io(void)
{
iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
}
#endif
#ifdef CONFIG_SOC_TI81XX
-void __init omapti81xx_map_common_io(void)
+void __init ti81xx_map_io(void)
{
iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
}
#endif
#ifdef CONFIG_SOC_AM33XX
-void __init omapam33xx_map_common_io(void)
+void __init am33xx_map_io(void)
{
iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
}
#endif
#ifdef CONFIG_ARCH_OMAP4
-void __init omap44xx_map_common_io(void)
+void __init omap4_map_io(void)
{
iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
omap_barriers_init();
@@ -309,7 +317,7 @@ void __init omap44xx_map_common_io(void)
#endif
#ifdef CONFIG_SOC_OMAP5
-void __init omap5_map_common_io(void)
+void __init omap5_map_io(void)
{
iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
}
@@ -371,8 +379,15 @@ static void __init omap_hwmod_init_postsetup(void)
#ifdef CONFIG_SOC_OMAP2420
void __init omap2420_init_early(void)
{
- omap2_set_globals_242x();
+ omap2_set_globals_tap(OMAP242X_CLASS, OMAP2_L4_IO_ADDRESS(0x48014000));
+ omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
+ OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);
omap2xxx_check_revision();
+ omap2xxx_cm_init();
omap2xxx_voltagedomains_init();
omap242x_powerdomains_init();
omap242x_clockdomains_init();
@@ -392,8 +407,15 @@ void __init omap2420_init_late(void)
#ifdef CONFIG_SOC_OMAP2430
void __init omap2430_init_early(void)
{
- omap2_set_globals_243x();
+ omap2_set_globals_tap(OMAP243X_CLASS, OMAP2_L4_IO_ADDRESS(0x4900a000));
+ omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
+ OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);
omap2xxx_check_revision();
+ omap2xxx_cm_init();
omap2xxx_voltagedomains_init();
omap243x_powerdomains_init();
omap243x_clockdomains_init();
@@ -417,9 +439,16 @@ void __init omap2430_init_late(void)
#ifdef CONFIG_ARCH_OMAP3
void __init omap3_init_early(void)
{
- omap2_set_globals_3xxx();
+ omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000));
+ omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
+ OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);
omap3xxx_check_revision();
omap3xxx_check_features();
+ omap3xxx_cm_init();
omap3xxx_voltagedomains_init();
omap3xxx_powerdomains_init();
omap3xxx_clockdomains_init();
@@ -450,7 +479,12 @@ void __init am35xx_init_early(void)
void __init ti81xx_init_early(void)
{
- omap2_set_globals_ti81xx();
+ omap2_set_globals_tap(OMAP343X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
omap3xxx_check_revision();
ti81xx_check_features();
omap3xxx_voltagedomains_init();
@@ -507,7 +541,12 @@ void __init ti81xx_init_late(void)
#ifdef CONFIG_SOC_AM33XX
void __init am33xx_init_early(void)
{
- omap2_set_globals_am33xx();
+ omap2_set_globals_tap(AM335X_CLASS,
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE));
+ omap2_set_globals_control(AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE));
+ omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL);
omap3xxx_check_revision();
ti81xx_check_features();
am33xx_voltagedomains_init();
@@ -522,7 +561,16 @@ void __init am33xx_init_early(void)
#ifdef CONFIG_ARCH_OMAP4
void __init omap4430_init_early(void)
{
- omap2_set_globals_443x();
+ omap2_set_globals_tap(OMAP443X_CLASS,
+ OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
+ OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE));
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
+ OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE));
+ omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE));
+ omap_prm_base_init();
+ omap_cm_base_init();
omap4xxx_check_revision();
omap4xxx_check_features();
omap44xx_voltagedomains_init();
@@ -544,7 +592,16 @@ void __init omap4430_init_late(void)
#ifdef CONFIG_SOC_OMAP5
void __init omap5_init_early(void)
{
- omap2_set_globals_5xxx();
+ omap2_set_globals_tap(OMAP54XX_CLASS,
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE),
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE));
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE));
+ omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
+ omap_prm_base_init();
+ omap_cm_base_init();
omap5xxx_check_revision();
}
#endif
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index a106c75c5338..bf496510eb5e 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -29,7 +29,7 @@
* FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
* Sidetone needs non-gated ICLK and sidetone autoidle is broken.
*/
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
static int omap3_enable_st_clock(unsigned int id, bool enable)
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
index 627e97e30743..aafdd4ca9f4f 100644
--- a/arch/arm/mach-omap2/msdi.c
+++ b/arch/arm/mach-omap2/msdi.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/platform_data/gpio-omap.h>
+#include "prm.h"
#include "common.h"
#include "control.h"
#include "omap_hwmod.h"
@@ -43,9 +44,6 @@
#define MSDI_CON_CLKD_MASK (0x3f << 0)
#define MSDI_CON_CLKD_SHIFT 0
-/* Maximum microseconds to wait for OMAP module to softreset */
-#define MAX_MODULE_SOFTRESET_WAIT 10000
-
/* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */
#define MSDI_TARGET_RESET_CLKD 0x3ff
diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c
new file mode 100644
index 000000000000..be6bc89ab1e8
--- /dev/null
+++ b/arch/arm/mach-omap2/omap2-restart.c
@@ -0,0 +1,65 @@
+/*
+ * omap2-restart.c - code common to all OMAP2xxx machines.
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Paul Walmsley
+ *
+ * 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/clk.h>
+#include <linux/io.h>
+
+#include "common.h"
+#include "prm2xxx.h"
+
+/*
+ * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set
+ * clock and the sys_ck. Used during the reset process
+ */
+static struct clk *reset_virt_prcm_set_ck, *reset_sys_ck;
+
+/* Reboot handling */
+
+/**
+ * omap2xxx_restart - Set DPLL to bypass mode for reboot to work
+ *
+ * Set the DPLL to bypass so that reboot completes successfully. No
+ * return value.
+ */
+void omap2xxx_restart(char mode, const char *cmd)
+{
+ u32 rate;
+
+ rate = clk_get_rate(reset_sys_ck);
+ clk_set_rate(reset_virt_prcm_set_ck, rate);
+
+ /* XXX Should save the cmd argument for use after the reboot */
+
+ omap2xxx_prm_dpll_reset(); /* never returns */
+ while (1);
+}
+
+/**
+ * omap2xxx_common_look_up_clks_for_reset - look up clocks needed for restart
+ *
+ * Some clocks need to be looked up in advance for the SoC restart
+ * operation to work - see omap2xxx_restart(). Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int __init omap2xxx_common_look_up_clks_for_reset(void)
+{
+ reset_virt_prcm_set_ck = clk_get(NULL, "virt_prcm_set");
+ if (IS_ERR(reset_virt_prcm_set_ck))
+ return -EINVAL;
+
+ reset_sys_ck = clk_get(NULL, "sys_ck");
+ if (IS_ERR(reset_sys_ck))
+ return -EINVAL;
+
+ return 0;
+}
+core_initcall(omap2xxx_common_look_up_clks_for_reset);
diff --git a/arch/arm/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c
new file mode 100644
index 000000000000..923c582189e5
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3-restart.c
@@ -0,0 +1,36 @@
+/*
+ * omap3-restart.c - Code common to all OMAP3xxx machines.
+ *
+ * Copyright (C) 2009, 2012 Texas Instruments
+ * Copyright (C) 2010 Nokia Corporation
+ * Tony Lindgren <tony@atomide.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/kernel.h>
+#include <linux/init.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "control.h"
+#include "prm3xxx.h"
+
+/* Global address base setup code */
+
+/**
+ * omap3xxx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ */
+void omap3xxx_restart(char mode, const char *cmd)
+{
+ omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
+ omap3xxx_prm_dpll3_reset(); /* never returns */
+ while (1);
+}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 3cfcd41bf8fa..5695885ea340 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -27,9 +27,12 @@
#include "omap-wakeupgen.h"
#include "soc.h"
+#include "iomap.h"
#include "common.h"
#include "mmc.h"
#include "hsmmc.h"
+#include "prminst44xx.h"
+#include "prcm_mpu44xx.h"
#include "omap4-sar-layout.h"
#include "omap-secure.h"
#include "sram.h"
@@ -279,3 +282,19 @@ int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
return 0;
}
#endif
+
+/**
+ * omap44xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ */
+void omap44xx_restart(char mode, const char *cmd)
+{
+ /* XXX Should save 'cmd' into scratchpad for use after reboot */
+ omap4_prminst_global_warm_sw_reset(); /* never returns */
+ while (1);
+}
+
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 87eee3b62a3c..139adca3bda1 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -141,25 +141,23 @@
#include "clock.h"
#include "omap_hwmod.h"
-#include <plat/prcm.h>
#include "soc.h"
#include "common.h"
#include "clockdomain.h"
#include "powerdomain.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
#include "cminst44xx.h"
#include "cm33xx.h"
-#include "prm2xxx_3xxx.h"
+#include "prm.h"
+#include "prm3xxx.h"
#include "prm44xx.h"
#include "prm33xx.h"
#include "prminst44xx.h"
#include "mux.h"
#include "pm.h"
-/* Maximum microseconds to wait for OMAP module to softreset */
-#define MAX_MODULE_SOFTRESET_WAIT 10000
-
/* Name of the OMAP hwmod for the MPU */
#define MPU_INITIATOR_NAME "mpu"
@@ -2063,7 +2061,8 @@ static int _enable(struct omap_hwmod *oh)
_enable_sysc(oh);
}
} else {
- _omap4_disable_module(oh);
+ if (soc_ops.disable_module)
+ soc_ops.disable_module(oh);
_disable_clocks(oh);
pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
oh->name, r);
@@ -2668,7 +2667,34 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
/* Static functions intended only for use in soc_ops field function pointers */
/**
- * _omap2_wait_target_ready - wait for a module to leave slave idle
+ * _omap2xxx_wait_target_ready - wait for a module to leave slave idle
+ * @oh: struct omap_hwmod *
+ *
+ * Wait for a module @oh to leave slave idle. Returns 0 if the module
+ * does not have an IDLEST bit or if the module successfully leaves
+ * slave idle; otherwise, pass along the return value of the
+ * appropriate *_cm*_wait_module_ready() function.
+ */
+static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->flags & HWMOD_NO_IDLEST)
+ return 0;
+
+ if (!_find_mpu_rt_port(oh))
+ return 0;
+
+ /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
+
+ return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
+ oh->prcm.omap2.idlest_reg_id,
+ oh->prcm.omap2.idlest_idle_bit);
+}
+
+/**
+ * _omap3xxx_wait_target_ready - wait for a module to leave slave idle
* @oh: struct omap_hwmod *
*
* Wait for a module @oh to leave slave idle. Returns 0 if the module
@@ -2676,7 +2702,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
* slave idle; otherwise, pass along the return value of the
* appropriate *_cm*_wait_module_ready() function.
*/
-static int _omap2_wait_target_ready(struct omap_hwmod *oh)
+static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh)
{
if (!oh)
return -EINVAL;
@@ -2689,9 +2715,9 @@ static int _omap2_wait_target_ready(struct omap_hwmod *oh)
/* XXX check module SIDLEMODE, hardreset status, enabled clocks */
- return omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
- oh->prcm.omap2.idlest_reg_id,
- oh->prcm.omap2.idlest_idle_bit);
+ return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
+ oh->prcm.omap2.idlest_reg_id,
+ oh->prcm.omap2.idlest_idle_bit);
}
/**
@@ -3959,8 +3985,13 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
*/
void __init omap_hwmod_init(void)
{
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- soc_ops.wait_target_ready = _omap2_wait_target_ready;
+ if (cpu_is_omap24xx()) {
+ soc_ops.wait_target_ready = _omap2xxx_wait_target_ready;
+ soc_ops.assert_hardreset = _omap2_assert_hardreset;
+ soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
+ soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
+ } else if (cpu_is_omap34xx()) {
+ soc_ops.wait_target_ready = _omap3xxx_wait_target_ready;
soc_ops.assert_hardreset = _omap2_assert_hardreset;
soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 9a2f5594a7dc..13e1f4303989 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -43,9 +43,9 @@
#include "soc.h"
#include "common.h"
#include "clock.h"
-#include "prm2xxx_3xxx.h"
+#include "prm2xxx.h"
#include "prm-regbits-24xx.h"
-#include "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
#include "sram.h"
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 11f9669eb7ed..770320061422 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -38,17 +38,15 @@
#include "clockdomain.h"
#include "powerdomain.h"
-#include <plat/prcm.h>
#include <plat-omap/dma-omap.h>
#include "soc.h"
#include "common.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
#include "gpmc.h"
#include "prm-regbits-34xx.h"
-
-#include "prm2xxx_3xxx.h"
+#include "prm3xxx.h"
#include "pm.h"
#include "sdrc.h"
#include "sram.h"
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 1678a3284233..dea62a9aad07 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -29,8 +29,6 @@
#include <asm/cpu.h>
-#include <plat/prcm.h>
-
#include "powerdomain.h"
#include "clockdomain.h"
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
deleted file mode 100644
index 3950ccfe5f4a..000000000000
--- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * OMAP2 and OMAP3 powerdomain control
- *
- * Copyright (C) 2009-2011 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
- *
- * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
- * 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/io.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/bug.h>
-
-#include <plat/prcm.h>
-
-#include "powerdomain.h"
-#include "prm.h"
-#include "prm-regbits-24xx.h"
-#include "prm-regbits-34xx.h"
-
-
-/* Common functions across OMAP2 and OMAP3 */
-static int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
-{
- omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
- (pwrst << OMAP_POWERSTATE_SHIFT),
- pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
- return 0;
-}
-
-static int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
-{
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP2_PM_PWSTCTRL,
- OMAP_POWERSTATE_MASK);
-}
-
-static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
-{
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP2_PM_PWSTST,
- OMAP_POWERSTATEST_MASK);
-}
-
-static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
- u8 pwrst)
-{
- u32 m;
-
- m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
-
- omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
- OMAP2_PM_PWSTCTRL);
-
- return 0;
-}
-
-static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
- u8 pwrst)
-{
- u32 m;
-
- m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
-
- omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
- OMAP2_PM_PWSTCTRL);
-
- return 0;
-}
-
-static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m;
-
- m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
-
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
- m);
-}
-
-static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m;
-
- m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
-
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP2_PM_PWSTCTRL, m);
-}
-
-static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
-{
- u32 v;
-
- v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
- omap2_prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
- pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
-
- return 0;
-}
-
-static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
-{
- u32 c = 0;
-
- /*
- * REVISIT: pwrdm_wait_transition() may be better implemented
- * via a callback and a periodic timer check -- how long do we expect
- * powerdomain transitions to take?
- */
-
- /* XXX Is this udelay() value meaningful? */
- while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
- OMAP_INTRANSITION_MASK) &&
- (c++ < PWRDM_TRANSITION_BAILOUT))
- udelay(1);
-
- if (c > PWRDM_TRANSITION_BAILOUT) {
- pr_err("powerdomain: %s: waited too long to complete transition\n",
- pwrdm->name);
- return -EAGAIN;
- }
-
- pr_debug("powerdomain: completed transition in %d loops\n", c);
-
- return 0;
-}
-
-/* Applicable only for OMAP3. Not supported on OMAP2 */
-static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
-{
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP3430_PM_PREPWSTST,
- OMAP3430_LASTPOWERSTATEENTERED_MASK);
-}
-
-static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
-{
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP2_PM_PWSTST,
- OMAP3430_LOGICSTATEST_MASK);
-}
-
-static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
-{
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP2_PM_PWSTCTRL,
- OMAP3430_LOGICSTATEST_MASK);
-}
-
-static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
-{
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP3430_PM_PREPWSTST,
- OMAP3430_LASTLOGICSTATEENTERED_MASK);
-}
-
-static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
-{
- switch (bank) {
- case 0:
- return OMAP3430_LASTMEM1STATEENTERED_MASK;
- case 1:
- return OMAP3430_LASTMEM2STATEENTERED_MASK;
- case 2:
- return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
- case 3:
- return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
- default:
- WARN_ON(1); /* should never happen */
- return -EEXIST;
- }
- return 0;
-}
-
-static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m;
-
- m = omap3_get_mem_bank_lastmemst_mask(bank);
-
- return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP3430_PM_PREPWSTST, m);
-}
-
-static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
-{
- omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
- return 0;
-}
-
-static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
-{
- return omap2_prm_rmw_mod_reg_bits(0,
- 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
- pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
-}
-
-static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
-{
- return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
- 0, pwrdm->prcm_offs,
- OMAP2_PM_PWSTCTRL);
-}
-
-struct pwrdm_ops omap2_pwrdm_operations = {
- .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
- .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
- .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
- .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
- .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
- .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
- .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
- .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
- .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
-};
-
-struct pwrdm_ops omap3_pwrdm_operations = {
- .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
- .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
- .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
- .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
- .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
- .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
- .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
- .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
- .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
- .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
- .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
- .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
- .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
- .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
- .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
- .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
- .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
-};
diff --git a/arch/arm/mach-omap2/powerdomain33xx.c b/arch/arm/mach-omap2/powerdomain33xx.c
deleted file mode 100644
index 67c5663899b6..000000000000
--- a/arch/arm/mach-omap2/powerdomain33xx.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * AM33XX Powerdomain control
- *
- * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
- *
- * Derived from mach-omap2/powerdomain44xx.c written by 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 as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/io.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-
-#include <plat/prcm.h>
-
-#include "powerdomain.h"
-#include "prm33xx.h"
-#include "prm-regbits-33xx.h"
-
-
-static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
-{
- am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
- (pwrst << OMAP_POWERSTATE_SHIFT),
- pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
- return 0;
-}
-
-static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
- v &= OMAP_POWERSTATE_MASK;
- v >>= OMAP_POWERSTATE_SHIFT;
-
- return v;
-}
-
-static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
- v &= OMAP_POWERSTATEST_MASK;
- v >>= OMAP_POWERSTATEST_SHIFT;
-
- return v;
-}
-
-static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
- v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
- v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
-
- return v;
-}
-
-static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
-{
- am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
- (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
- pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
- return 0;
-}
-
-static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
-{
- am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
- AM33XX_LASTPOWERSTATEENTERED_MASK,
- pwrdm->prcm_offs, pwrdm->pwrstst_offs);
- return 0;
-}
-
-static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
-{
- u32 m;
-
- m = pwrdm->logicretstate_mask;
- if (!m)
- return -EINVAL;
-
- am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
- pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
-
- return 0;
-}
-
-static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
- v &= AM33XX_LOGICSTATEST_MASK;
- v >>= AM33XX_LOGICSTATEST_SHIFT;
-
- return v;
-}
-
-static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
-{
- u32 v, m;
-
- m = pwrdm->logicretstate_mask;
- if (!m)
- return -EINVAL;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
- v &= m;
- v >>= __ffs(m);
-
- return v;
-}
-
-static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
- u8 pwrst)
-{
- u32 m;
-
- m = pwrdm->mem_on_mask[bank];
- if (!m)
- return -EINVAL;
-
- am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
- pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
-
- return 0;
-}
-
-static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
- u8 pwrst)
-{
- u32 m;
-
- m = pwrdm->mem_ret_mask[bank];
- if (!m)
- return -EINVAL;
-
- am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
- pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
-
- return 0;
-}
-
-static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m, v;
-
- m = pwrdm->mem_pwrst_mask[bank];
- if (!m)
- return -EINVAL;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
- v &= m;
- v >>= __ffs(m);
-
- return v;
-}
-
-static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m, v;
-
- m = pwrdm->mem_retst_mask[bank];
- if (!m)
- return -EINVAL;
-
- v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
- v &= m;
- v >>= __ffs(m);
-
- return v;
-}
-
-static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
-{
- u32 c = 0;
-
- /*
- * REVISIT: pwrdm_wait_transition() may be better implemented
- * via a callback and a periodic timer check -- how long do we expect
- * powerdomain transitions to take?
- */
-
- /* XXX Is this udelay() value meaningful? */
- while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
- & OMAP_INTRANSITION_MASK) &&
- (c++ < PWRDM_TRANSITION_BAILOUT))
- udelay(1);
-
- if (c > PWRDM_TRANSITION_BAILOUT) {
- pr_err("powerdomain: %s: waited too long to complete transition\n",
- pwrdm->name);
- return -EAGAIN;
- }
-
- pr_debug("powerdomain: completed transition in %d loops\n", c);
-
- return 0;
-}
-
-struct pwrdm_ops am33xx_pwrdm_operations = {
- .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
- .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
- .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
- .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
- .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
- .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
- .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
- .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
- .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
- .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
- .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
- .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
- .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
- .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
-};
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
deleted file mode 100644
index aceb4f464c9b..000000000000
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * OMAP4 powerdomain control
- *
- * Copyright (C) 2009-2010, 2012 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
- *
- * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
- * 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/io.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/bug.h>
-
-#include "powerdomain.h"
-#include <plat/prcm.h>
-#include "prm2xxx_3xxx.h"
-#include "prm44xx.h"
-#include "prminst44xx.h"
-#include "prm-regbits-44xx.h"
-
-static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
-{
- omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
- (pwrst << OMAP_POWERSTATE_SHIFT),
- pwrdm->prcm_partition,
- pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
- return 0;
-}
-
-static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTCTRL);
- v &= OMAP_POWERSTATE_MASK;
- v >>= OMAP_POWERSTATE_SHIFT;
-
- return v;
-}
-
-static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTST);
- v &= OMAP_POWERSTATEST_MASK;
- v >>= OMAP_POWERSTATEST_SHIFT;
-
- return v;
-}
-
-static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTST);
- v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
- v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
-
- return v;
-}
-
-static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
-{
- omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
- (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
- pwrdm->prcm_partition,
- pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
- return 0;
-}
-
-static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
-{
- omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
- OMAP4430_LASTPOWERSTATEENTERED_MASK,
- pwrdm->prcm_partition,
- pwrdm->prcm_offs, OMAP4_PM_PWSTST);
- return 0;
-}
-
-static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
-{
- u32 v;
-
- v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
- omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
- pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTCTRL);
-
- return 0;
-}
-
-static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
- u8 pwrst)
-{
- u32 m;
-
- m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
-
- omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
- pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTCTRL);
-
- return 0;
-}
-
-static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
- u8 pwrst)
-{
- u32 m;
-
- m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
-
- omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
- pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTCTRL);
-
- return 0;
-}
-
-static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTST);
- v &= OMAP4430_LOGICSTATEST_MASK;
- v >>= OMAP4430_LOGICSTATEST_SHIFT;
-
- return v;
-}
-
-static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
-{
- u32 v;
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTCTRL);
- v &= OMAP4430_LOGICRETSTATE_MASK;
- v >>= OMAP4430_LOGICRETSTATE_SHIFT;
-
- return v;
-}
-
-/**
- * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
- * @pwrdm: struct powerdomain * to read the state for
- *
- * Reads the previous logic powerstate for a powerdomain. This
- * function must determine the previous logic powerstate by first
- * checking the previous powerstate for the domain. If that was OFF,
- * then logic has been lost. If previous state was RETENTION, the
- * function reads the setting for the next retention logic state to
- * see the actual value. In every other case, the logic is
- * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
- * depending whether the logic was retained or not.
- */
-static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
-{
- int state;
-
- state = omap4_pwrdm_read_prev_pwrst(pwrdm);
-
- if (state == PWRDM_POWER_OFF)
- return PWRDM_POWER_OFF;
-
- if (state != PWRDM_POWER_RET)
- return PWRDM_POWER_RET;
-
- return omap4_pwrdm_read_logic_retst(pwrdm);
-}
-
-static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m, v;
-
- m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTST);
- v &= m;
- v >>= __ffs(m);
-
- return v;
-}
-
-static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
-{
- u32 m, v;
-
- m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
-
- v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
- OMAP4_PM_PWSTCTRL);
- v &= m;
- v >>= __ffs(m);
-
- return v;
-}
-
-/**
- * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
- * @pwrdm: struct powerdomain * to read mem powerstate for
- * @bank: memory bank index
- *
- * Reads the previous memory powerstate for a powerdomain. This
- * function must determine the previous memory powerstate by first
- * checking the previous powerstate for the domain. If that was OFF,
- * then logic has been lost. If previous state was RETENTION, the
- * function reads the setting for the next memory retention state to
- * see the actual value. In every other case, the logic is
- * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
- * depending whether logic was retained or not.
- */
-static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
-{
- int state;
-
- state = omap4_pwrdm_read_prev_pwrst(pwrdm);
-
- if (state == PWRDM_POWER_OFF)
- return PWRDM_POWER_OFF;
-
- if (state != PWRDM_POWER_RET)
- return PWRDM_POWER_RET;
-
- return omap4_pwrdm_read_mem_retst(pwrdm, bank);
-}
-
-static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
-{
- u32 c = 0;
-
- /*
- * REVISIT: pwrdm_wait_transition() may be better implemented
- * via a callback and a periodic timer check -- how long do we expect
- * powerdomain transitions to take?
- */
-
- /* XXX Is this udelay() value meaningful? */
- while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
- pwrdm->prcm_offs,
- OMAP4_PM_PWSTST) &
- OMAP_INTRANSITION_MASK) &&
- (c++ < PWRDM_TRANSITION_BAILOUT))
- udelay(1);
-
- if (c > PWRDM_TRANSITION_BAILOUT) {
- pr_err("powerdomain: %s: waited too long to complete transition\n",
- pwrdm->name);
- return -EAGAIN;
- }
-
- pr_debug("powerdomain: completed transition in %d loops\n", c);
-
- return 0;
-}
-
-struct pwrdm_ops omap4_pwrdm_operations = {
- .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
- .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
- .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
- .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
- .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
- .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
- .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
- .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
- .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst,
- .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
- .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
- .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
- .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
- .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
- .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
- .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
-};
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 72df97482cc0..c7d355fafd24 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -406,11 +406,6 @@
#define OMAP3430_EN_CORE_MASK (1 << 0)
-/*
- * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
- * submodule to exit hardreset
- */
-#define MAX_MODULE_HARDRESET_WAIT 10000
/*
* Maximum time(us) it takes to output the signal WUCLKOUT of the last
@@ -419,24 +414,7 @@
* microseconds on OMAP4, so this timeout may be too high.
*/
#define MAX_IOPAD_LATCH_TIME 100
-
# ifndef __ASSEMBLER__
-extern void __iomem *prm_base;
-extern void __iomem *cm_base;
-extern void __iomem *cm2_base;
-extern void __iomem *prcm_mpu_base;
-
-#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
-extern void omap_prm_base_init(void);
-extern void omap_cm_base_init(void);
-#else
-static inline void omap_prm_base_init(void)
-{
-}
-static inline void omap_cm_base_init(void)
-{
-}
-#endif
/**
* struct omap_prcm_irq - describes a PRCM interrupt bit
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
deleted file mode 100644
index cff270a178c5..000000000000
--- a/arch/arm/mach-omap2/prcm.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/prcm.c
- *
- * OMAP 24xx Power Reset and Clock Management (PRCM) functions
- *
- * Copyright (C) 2005 Nokia Corporation
- *
- * Written by Tony Lindgren <tony.lindgren@nokia.com>
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Rajendra Nayak <rnayak@ti.com>
- *
- * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
- * Upgraded with OMAP4 support by Abhijit Pagare <abhijitpagare@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/clk.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/export.h>
-
-#include "common.h"
-#include <plat/prcm.h>
-
-#include "soc.h"
-#include "clock.h"
-#include "clock2xxx.h"
-#include "cm2xxx_3xxx.h"
-#include "prm2xxx_3xxx.h"
-#include "prm44xx.h"
-#include "prminst44xx.h"
-#include "cminst44xx.h"
-#include "prm-regbits-24xx.h"
-#include "prm-regbits-44xx.h"
-#include "control.h"
-
-void __iomem *prm_base;
-void __iomem *cm_base;
-void __iomem *cm2_base;
-void __iomem *prcm_mpu_base;
-
-#define MAX_MODULE_ENABLE_WAIT 100000
-
-u32 omap_prcm_get_reset_sources(void)
-{
- /* XXX This presumably needs modification for 34XX */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- return omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
- if (cpu_is_omap44xx())
- return omap2_prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
-
- return 0;
-}
-EXPORT_SYMBOL(omap_prcm_get_reset_sources);
-
-/* Resets clock rates and reboots the system. Only called from system.h */
-void omap_prcm_restart(char mode, const char *cmd)
-{
- s16 prcm_offs = 0;
-
- if (cpu_is_omap24xx()) {
- omap2xxx_clk_prepare_for_reboot();
-
- prcm_offs = WKUP_MOD;
- } else if (cpu_is_omap34xx()) {
- prcm_offs = OMAP3430_GR_MOD;
- omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
- } else if (cpu_is_omap44xx()) {
- omap4_prminst_global_warm_sw_reset(); /* never returns */
- } else {
- WARN_ON(1);
- }
-
- /*
- * As per Errata i520, in some cases, user will not be able to
- * access DDR memory after warm-reset.
- * This situation occurs while the warm-reset happens during a read
- * access to DDR memory. In that particular condition, DDR memory
- * does not respond to a corrupted read command due to the warm
- * reset occurrence but SDRC is waiting for read completion.
- * SDRC is not sensitive to the warm reset, but the interconnect is
- * reset on the fly, thus causing a misalignment between SDRC logic,
- * interconnect logic and DDR memory state.
- * WORKAROUND:
- * Steps to perform before a Warm reset is trigged:
- * 1. enable self-refresh on idle request
- * 2. put SDRC in idle
- * 3. wait until SDRC goes to idle
- * 4. generate SW reset (Global SW reset)
- *
- * Steps to be performed after warm reset occurs (in bootloader):
- * if HW warm reset is the source, apply below steps before any
- * accesses to SDRAM:
- * 1. Reset SMS and SDRC and wait till reset is complete
- * 2. Re-initialize SMS, SDRC and memory
- *
- * NOTE: Above work around is required only if arch reset is implemented
- * using Global SW reset(GLOBAL_SW_RST). DPLL3 reset does not need
- * the WA since it resets SDRC as well as part of cold reset.
- */
-
- /* XXX should be moved to some OMAP2/3 specific code */
- omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
- OMAP2_RM_RSTCTRL);
- omap2_prm_read_mod_reg(prcm_offs, OMAP2_RM_RSTCTRL); /* OCP barrier */
-}
-
-/**
- * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
- * @reg: physical address of module IDLEST register
- * @mask: value to mask against to determine if the module is active
- * @idlest: idle state indicator (0 or 1) for the clock
- * @name: name of the clock (for printk)
- *
- * Returns 1 if the module indicated readiness in time, or 0 if it
- * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
- *
- * XXX This function is deprecated. It should be removed once the
- * hwmod conversion is complete.
- */
-int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
- const char *name)
-{
- int i = 0;
- int ena = 0;
-
- if (idlest)
- ena = 0;
- else
- ena = mask;
-
- /* Wait for lock */
- omap_test_timeout(((__raw_readl(reg) & mask) == ena),
- MAX_MODULE_ENABLE_WAIT, i);
-
- if (i < MAX_MODULE_ENABLE_WAIT)
- pr_debug("cm: Module associated with clock %s ready after %d loops\n",
- name, i);
- else
- pr_err("cm: Module associated with clock %s didn't enable in %d tries\n",
- name, MAX_MODULE_ENABLE_WAIT);
-
- return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
-};
-
-void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
-{
- if (omap2_globals->prm)
- prm_base = omap2_globals->prm;
- if (omap2_globals->cm)
- cm_base = omap2_globals->cm;
- if (omap2_globals->cm2)
- cm2_base = omap2_globals->cm2;
- if (omap2_globals->prcm_mpu)
- prcm_mpu_base = omap2_globals->prcm_mpu;
-
- if (cpu_is_omap44xx() || soc_is_omap54xx()) {
- omap_prm_base_init();
- omap_cm_base_init();
- }
-}
-
-/*
- * Stubbed functions so that common files continue to build when
- * custom builds are used
- * XXX These are temporary and should be removed at the earliest possible
- * opportunity
- */
-int __weak omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs,
- u16 clkctrl_offs)
-{
- return 0;
-}
-
-void __weak omap4_cminst_module_enable(u8 mode, u8 part, u16 inst,
- s16 cdoffs, u16 clkctrl_offs)
-{
-}
-
-void __weak omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
- u16 clkctrl_offs)
-{
-}
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c
index 928dbd4f20ed..c30e44a7fab0 100644
--- a/arch/arm/mach-omap2/prcm_mpu44xx.c
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.c
@@ -20,6 +20,12 @@
#include "prcm_mpu44xx.h"
#include "cm-regbits-44xx.h"
+/*
+ * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP
+ * block registers
+ */
+void __iomem *prcm_mpu_base;
+
/* PRCM_MPU low-level functions */
u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg)
@@ -43,3 +49,14 @@ u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
return v;
}
+
+/**
+ * omap2_set_globals_prcm_mpu - set the MPU PRCM base address (for early use)
+ * @prcm_mpu: PRCM_MPU base virtual address
+ *
+ * XXX Will be replaced when the PRM/CM drivers are completed.
+ */
+void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu)
+{
+ prcm_mpu_base = prcm_mpu;
+}
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h
index 8a6e250f04b5..884af7bb4afd 100644
--- a/arch/arm/mach-omap2/prcm_mpu44xx.h
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.h
@@ -1,7 +1,7 @@
/*
* OMAP44xx PRCM MPU instance offset macros
*
- * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010, 2012 Texas Instruments, Inc.
* Copyright (C) 2010 Nokia Corporation
*
* Paul Walmsley (paul@pwsan.com)
@@ -25,6 +25,12 @@
#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
+#include "common.h"
+
+# ifndef __ASSEMBLER__
+extern void __iomem *prcm_mpu_base;
+# endif
+
#define OMAP4430_PRCM_MPU_BASE 0x48243000
#define OMAP44XX_PRCM_MPU_REGADDR(inst, reg) \
@@ -98,6 +104,7 @@ extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx);
extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
extern u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst,
s16 idx);
+extern void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu);
# endif
#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h
index 6ac966103f34..638da6dd41c3 100644
--- a/arch/arm/mach-omap2/prm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-24xx.h
@@ -14,7 +14,7 @@
* published by the Free Software Foundation.
*/
-#include "prm2xxx_3xxx.h"
+#include "prm2xxx.h"
/* Bits shared between registers */
@@ -209,9 +209,13 @@
/* RM_RSTST_WKUP specific bits */
/* 2430 calls EXTWMPU_RST "EXTWARM_RST" and GLOBALWMPU_RST "GLOBALWARM_RST" */
+#define OMAP24XX_EXTWMPU_RST_SHIFT 6
#define OMAP24XX_EXTWMPU_RST_MASK (1 << 6)
+#define OMAP24XX_SECU_WD_RST_SHIFT 5
#define OMAP24XX_SECU_WD_RST_MASK (1 << 5)
+#define OMAP24XX_MPU_WD_RST_SHIFT 4
#define OMAP24XX_MPU_WD_RST_MASK (1 << 4)
+#define OMAP24XX_SECU_VIOL_RST_SHIFT 3
#define OMAP24XX_SECU_VIOL_RST_MASK (1 << 3)
/* PM_WKEN_WKUP specific bits */
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 64c087af6a8b..838b594d4e13 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -14,7 +14,7 @@
#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
-#include "prm2xxx_3xxx.h"
+#include "prm3xxx.h"
/* Shared register bits */
@@ -509,15 +509,25 @@
#define OMAP3430_RSTTIME1_MASK (0xff << 0)
/* PRM_RSTST */
+#define OMAP3430_ICECRUSHER_RST_SHIFT 10
#define OMAP3430_ICECRUSHER_RST_MASK (1 << 10)
+#define OMAP3430_ICEPICK_RST_SHIFT 9
#define OMAP3430_ICEPICK_RST_MASK (1 << 9)
+#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT 8
#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_MASK (1 << 8)
+#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT 7
#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_MASK (1 << 7)
+#define OMAP3430_EXTERNAL_WARM_RST_SHIFT 6
#define OMAP3430_EXTERNAL_WARM_RST_MASK (1 << 6)
+#define OMAP3430_SECURE_WD_RST_SHIFT 5
#define OMAP3430_SECURE_WD_RST_MASK (1 << 5)
+#define OMAP3430_MPU_WD_RST_SHIFT 4
#define OMAP3430_MPU_WD_RST_MASK (1 << 4)
+#define OMAP3430_SECURITY_VIOL_RST_SHIFT 3
#define OMAP3430_SECURITY_VIOL_RST_MASK (1 << 3)
+#define OMAP3430_GLOBAL_SW_RST_SHIFT 1
#define OMAP3430_GLOBAL_SW_RST_MASK (1 << 1)
+#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0
#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0)
/* PRM_VOLTCTRL */
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 39d562169d18..a1a266ce90da 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -1,7 +1,7 @@
/*
* OMAP2/3/4 Power/Reset Management (PRM) bitfield definitions
*
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
* Copyright (C) 2010 Nokia Corporation
*
* Paul Walmsley
@@ -15,6 +15,28 @@
#include "prcm-common.h"
+# ifndef __ASSEMBLER__
+extern void __iomem *prm_base;
+extern void omap2_set_globals_prm(void __iomem *prm);
+# endif
+
+
+/*
+ * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP
+ * module to softreset
+ */
+#define MAX_MODULE_SOFTRESET_WAIT 10000
+
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+/*
+ * Register bitfields
+ */
+
/*
* 24XX: PM_PWSTST_CORE, PM_PWSTST_GFX, PM_PWSTST_MPU, PM_PWSTST_DSP
*
@@ -52,5 +74,58 @@
#define OMAP_POWERSTATE_SHIFT 0
#define OMAP_POWERSTATE_MASK (0x3 << 0)
+/*
+ * Standardized OMAP reset source bits
+ *
+ * To the extent these happen to match the hardware register bit
+ * shifts, it's purely coincidental. Used by omap-wdt.c.
+ * OMAP_UNKNOWN_RST_SRC_ID_SHIFT is a special value, used whenever
+ * there are any bits remaining in the global PRM_RSTST register that
+ * haven't been identified, or when the PRM code for the current SoC
+ * doesn't know how to interpret the register.
+ */
+#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
+#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
+#define OMAP_SECU_VIOL_RST_SRC_ID_SHIFT 2
+#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
+#define OMAP_SECU_WD_RST_SRC_ID_SHIFT 4
+#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
+#define OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT 6
+#define OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT 7
+#define OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT 8
+#define OMAP_ICEPICK_RST_SRC_ID_SHIFT 9
+#define OMAP_ICECRUSHER_RST_SRC_ID_SHIFT 10
+#define OMAP_C2C_RST_SRC_ID_SHIFT 11
+#define OMAP_UNKNOWN_RST_SRC_ID_SHIFT 12
+
+#ifndef __ASSEMBLER__
+
+/**
+ * struct prm_reset_src_map - map register bitshifts to standard bitshifts
+ * @reg_shift: bitshift in the PRM reset source register
+ * @std_shift: bitshift equivalent in the standard reset source list
+ *
+ * The fields are signed because -1 is used as a terminator.
+ */
+struct prm_reset_src_map {
+ s8 reg_shift;
+ s8 std_shift;
+};
+
+/**
+ * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
+ * @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl
+ */
+struct prm_ll_data {
+ u32 (*read_reset_sources)(void);
+};
+
+extern int prm_register(struct prm_ll_data *pld);
+extern int prm_unregister(struct prm_ll_data *pld);
+
+extern u32 prm_read_reset_sources(void);
+
+#endif
+
#endif
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
new file mode 100644
index 000000000000..bf24fc47603b
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -0,0 +1,139 @@
+/*
+ * OMAP2xxx PRM module functions
+ *
+ * Copyright (C) 2010-2012 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * BenoƮt Cousson
+ * Paul Walmsley
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include "common.h"
+#include <plat/cpu.h>
+
+#include "vp.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "prm2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP
+ * hardware register (which are specific to the OMAP2xxx SoCs) to
+ * reset source ID bit shifts (which is an OMAP SoC-independent
+ * enumeration)
+ */
+static struct prm_reset_src_map omap2xxx_prm_reset_src_map[] = {
+ { OMAP_GLOBALCOLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
+ { OMAP_GLOBALWARM_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
+ { OMAP24XX_SECU_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
+ { OMAP24XX_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP24XX_SECU_WD_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
+ { OMAP24XX_EXTWMPU_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
+ { -1, -1 },
+};
+
+/**
+ * omap2xxx_prm_read_reset_sources - return the last SoC reset source
+ *
+ * Return a u32 representing the last reset sources of the SoC. The
+ * returned reset source bits are standardized across OMAP SoCs.
+ */
+static u32 omap2xxx_prm_read_reset_sources(void)
+{
+ struct prm_reset_src_map *p;
+ u32 r = 0;
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
+
+ p = omap2xxx_prm_reset_src_map;
+ while (p->reg_shift >= 0 && p->std_shift >= 0) {
+ if (v & (1 << p->reg_shift))
+ r |= 1 << p->std_shift;
+ p++;
+ }
+
+ return r;
+}
+
+/**
+ * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC
+ *
+ * Set the DPLL reset bit, which should reboot the SoC. This is the
+ * recommended way to restart the SoC. No return value.
+ */
+void omap2xxx_prm_dpll_reset(void)
+{
+ omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD,
+ OMAP2_RM_RSTCTRL);
+ /* OCP barrier */
+ omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTCTRL);
+}
+
+int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+struct pwrdm_ops omap2_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
+ .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
+ .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
+ .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
+ .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
+};
+
+/*
+ *
+ */
+
+static struct prm_ll_data omap2xxx_prm_ll_data = {
+ .read_reset_sources = &omap2xxx_prm_read_reset_sources,
+};
+
+static int __init omap2xxx_prm_init(void)
+{
+ if (!cpu_is_omap24xx())
+ return 0;
+
+ return prm_register(&omap2xxx_prm_ll_data);
+}
+subsys_initcall(omap2xxx_prm_init);
+
+static void __exit omap2xxx_prm_exit(void)
+{
+ if (!cpu_is_omap24xx())
+ return;
+
+ /* Should never happen */
+ WARN(prm_unregister(&omap2xxx_prm_ll_data),
+ "%s: prm_ll_data function pointer mismatch\n", __func__);
+}
+__exitcall(omap2xxx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
new file mode 100644
index 000000000000..fe8a14f190ab
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -0,0 +1,134 @@
+/*
+ * OMAP2xxx Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * The PRM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The PRM on OMAP4 has a new register layout, and is handled
+ * in a separate file.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM2XXX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm2xxx_3xxx.h"
+
+#define OMAP2420_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
+#define OMAP2430_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
+
+/*
+ * OMAP2-specific global PRM registers
+ * Use __raw_{read,write}l() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE
+ * bits.)
+ *
+ */
+
+#define OMAP2_PRCM_REVISION_OFFSET 0x0000
+#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
+#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
+
+#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
+#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
+#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
+
+#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
+#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
+#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
+#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
+#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
+#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
+#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
+#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
+#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
+#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
+#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
+#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
+#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
+#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
+#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
+#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
+#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
+#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
+#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
+
+#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
+
+#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
+
+#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
+#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
+#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
+#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
+#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
+#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
+#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
+#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
+#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
+#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
+
+/*
+ * Module specific PRM register offsets from PRM_BASE + domain offset
+ *
+ * Use prm_{read,write}_mod_reg() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * {PM,RM}_* on both OMAP2/3 SoC families.. (The exceptions are the
+ * IRQSTATUS and IRQENABLE bits.)
+ */
+
+/* Register offsets appearing on both OMAP2 and OMAP3 */
+
+#define OMAP2_RM_RSTCTRL 0x0050
+#define OMAP2_RM_RSTTIME 0x0054
+#define OMAP2_RM_RSTST 0x0058
+#define OMAP2_PM_PWSTCTRL 0x00e0
+#define OMAP2_PM_PWSTST 0x00e4
+
+#define PM_WKEN 0x00a0
+#define PM_WKEN1 PM_WKEN
+#define PM_WKST 0x00b0
+#define PM_WKST1 PM_WKST
+#define PM_WKDEP 0x00c8
+#define PM_EVGENCTRL 0x00d4
+#define PM_EVGENONTIM 0x00d8
+#define PM_EVGENOFFTIM 0x00dc
+
+/* OMAP2xxx specific register offsets */
+#define OMAP24XX_PM_WKEN2 0x00a4
+#define OMAP24XX_PM_WKST2 0x00b4
+
+#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
+#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
+#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
+#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
+
+#ifndef __ASSEMBLER__
+/* Function prototypes */
+extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
+extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
+
+extern void omap2xxx_prm_dpll_reset(void);
+
+extern int __init prm2xxx_init(void);
+extern int __exit prm2xxx_exit(void);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9529984d8d2b..30517f5af707 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -15,82 +15,12 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/irq.h>
-#include <plat/prcm.h>
-
-#include "soc.h"
#include "common.h"
-#include "vp.h"
-
+#include "powerdomain.h"
#include "prm2xxx_3xxx.h"
-#include "cm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
-#include "prm-regbits-34xx.h"
-
-static const struct omap_prcm_irq omap3_prcm_irqs[] = {
- OMAP_PRCM_IRQ("wkup", 0, 0),
- OMAP_PRCM_IRQ("io", 9, 1),
-};
-
-static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
- .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
- .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
- .nr_regs = 1,
- .irqs = omap3_prcm_irqs,
- .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
- .irq = 11 + OMAP_INTC_START,
- .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
- .ocp_barrier = &omap3xxx_prm_ocp_barrier,
- .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
- .restore_irqen = &omap3xxx_prm_restore_irqen,
-};
-
-u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
-{
- return __raw_readl(prm_base + module + idx);
-}
-
-void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
-{
- __raw_writel(val, prm_base + module + idx);
-}
-
-/* Read-modify-write a register in a PRM module. Caller must lock */
-u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
-{
- u32 v;
-
- v = omap2_prm_read_mod_reg(module, idx);
- v &= ~mask;
- v |= bits;
- omap2_prm_write_mod_reg(v, module, idx);
-
- return v;
-}
-
-/* Read a PRM register, AND it, and shift the result down to bit 0 */
-u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
-{
- u32 v;
-
- v = omap2_prm_read_mod_reg(domain, idx);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
-u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
-}
-
-u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
-}
-
+#include "clockdomain.h"
/**
* omap2_prm_is_hardreset_asserted - read the HW reset line state of
@@ -104,9 +34,6 @@ u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
*/
int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
{
- if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
- return -EINVAL;
-
return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
(1 << shift));
}
@@ -127,9 +54,6 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
{
u32 mask;
- if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
- return -EINVAL;
-
mask = 1 << shift;
omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
@@ -156,9 +80,6 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
u32 rst, st;
int c;
- if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
- return -EINVAL;
-
rst = 1 << rst_shift;
st = 1 << st_shift;
@@ -178,188 +99,155 @@ 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;
-};
-
-static 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;
-}
+/* Powerdomain low-level functions */
-void omap3_prm_vp_clear_txdone(u8 vp_id)
+/* Common functions across OMAP2 and OMAP3 */
+int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
{
- struct omap3_vp *vp = &omap3_vp[vp_id];
-
- omap2_prm_write_mod_reg(vp->tranxdone_status,
- OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+ return 0;
}
-u32 omap3_prm_vcvp_read(u8 offset)
+int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
{
- return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP_POWERSTATE_MASK);
}
-void omap3_prm_vcvp_write(u32 val, u8 offset)
+int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
{
- omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP_POWERSTATEST_MASK);
}
-u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
{
- return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
+
+ omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
}
-/**
- * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
- * @events: ptr to a u32, preallocated by caller
- *
- * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
- * MPU IRQs, and store the result into the u32 pointed to by @events.
- * No return value.
- */
-void omap3xxx_prm_read_pending_irqs(unsigned long *events)
+int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
{
- u32 mask, st;
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
- /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
- mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
- st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
- events[0] = mask & st;
+ return 0;
}
-/**
- * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
- *
- * Force any buffered writes to the PRM IP block to complete. Needed
- * by the PRM IRQ handler, which reads and writes directly to the IP
- * block, to avoid race conditions after acknowledging or clearing IRQ
- * bits. No return value.
- */
-void omap3xxx_prm_ocp_barrier(void)
+int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
{
- omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
+ m);
}
-/**
- * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
- * @saved_mask: ptr to a u32 array to save IRQENABLE bits
- *
- * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
- * must be allocated by the caller. Intended to be used in the PRM
- * interrupt handler suspend callback. The OCP barrier is needed to
- * ensure the write to disable PRM interrupts reaches the PRM before
- * returning; otherwise, spurious interrupts might occur. No return
- * value.
- */
-void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
+int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
{
- saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
- OMAP3_PRM_IRQENABLE_MPU_OFFSET);
- omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
- /* OCP barrier */
- omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL, m);
}
-/**
- * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
- * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
- *
- * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
- * to be used in the PRM interrupt handler resume callback to restore
- * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
- * barrier should be needed here; any pending PRM interrupts will fire
- * once the writes reach the PRM. No return value.
- */
-void omap3xxx_prm_restore_irqen(u32 *saved_mask)
+int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
{
- omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
- OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ u32 v;
+
+ v = pwrst << __ffs(OMAP_LOGICRETSTATE_MASK);
+ omap2_prm_rmw_mod_reg_bits(OMAP_LOGICRETSTATE_MASK, v, pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
}
-/**
- * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
- *
- * Clear any previously-latched I/O wakeup events and ensure that the
- * I/O wakeup gates are aligned with the current mux settings. Works
- * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
- * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
- * return value.
- */
-void omap3xxx_prm_reconfigure_io_chain(void)
+int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
{
- int i = 0;
+ u32 c = 0;
- omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKEN);
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
- omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
- OMAP3430_ST_IO_CHAIN_MASK,
- MAX_IOPAD_LATCH_TIME, i);
- if (i == MAX_IOPAD_LATCH_TIME)
- pr_warn("PRM: I/O chain clock line assertion timed out\n");
+ /* XXX Is this udelay() value meaningful? */
+ while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
+ OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
- omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKEN);
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ pr_err("powerdomain: %s: waited too long to complete transition\n",
+ pwrdm->name);
+ return -EAGAIN;
+ }
- omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKST);
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
- omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
+ return 0;
}
-/**
- * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
- *
- * Activates the I/O wakeup event latches and allows events logged by
- * those latches to signal a wakeup event to the PRCM. For I/O
- * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
- * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
- * No return value.
- */
-static void __init omap3xxx_prm_enable_io_wakeup(void)
+int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ return 0;
+}
+
+int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ return 0;
+}
+
+int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
{
- if (omap3_has_io_wakeup())
- omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
- PM_WKEN);
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ PM_WKDEP, (1 << clkdm2->dep_bit));
}
-static int __init omap3xxx_prcm_init(void)
+int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
{
- int ret = 0;
-
- if (cpu_is_omap34xx()) {
- omap3xxx_prm_enable_io_wakeup();
- ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
- if (!ret)
- irq_set_status_flags(omap_prcm_event_to_irq("io"),
- IRQ_NOAUTOEN);
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ /* PRM accesses are slow, so minimize them */
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->wkdep_usecount, 0);
}
- return ret;
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ PM_WKDEP);
+ return 0;
}
-subsys_initcall(omap3xxx_prcm_init);
+
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index c19d249b4816..78532d6fecd7 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -1,7 +1,7 @@
/*
- * OMAP2/3 Power/Reset Management (PRM) register definitions
+ * OMAP2xxx/3xxx-common Power/Reset Management (PRM) register definitions
*
- * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc.
* Copyright (C) 2008-2010 Nokia Corporation
* Paul Walmsley
*
@@ -19,160 +19,6 @@
#include "prcm-common.h"
#include "prm.h"
-#define OMAP2420_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
-#define OMAP2430_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
-#define OMAP34XX_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
-
-
-/*
- * OMAP2-specific global PRM registers
- * Use __raw_{read,write}l() with these registers.
- *
- * With a few exceptions, these are the register names beginning with
- * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE
- * bits.)
- *
- */
-
-#define OMAP2_PRCM_REVISION_OFFSET 0x0000
-#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
-#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
-
-#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
-#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
-#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
-#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
-
-#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
-#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
-#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
-#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
-#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
-#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
-#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
-#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
-#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
-#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
-#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
-#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
-#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
-#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
-#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
-#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
-#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
-#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
-#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
-#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
-
-#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
-
-#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
-#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
-
-#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
-#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
-#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
-#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
-#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
-#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
-#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
-#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
-#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
-#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
-
-/*
- * OMAP3-specific global PRM registers
- * Use __raw_{read,write}l() with these registers.
- *
- * With a few exceptions, these are the register names beginning with
- * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE
- * bits.)
- */
-
-#define OMAP3_PRM_REVISION_OFFSET 0x0004
-#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
-#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
-#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
-
-#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
-#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
-#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
-#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
-
-
-#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
-#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
-#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
-#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
-#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
-#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
-#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
-#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
-#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
-#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
-#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
-#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
-#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
-#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
-#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
-#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
-#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
-#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
-#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
-#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
-#define OMAP3_PRM_RSTST_OFFSET 0x0058
-#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
-#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
-#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
-#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
-#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
-#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
-#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
-#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
-#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
-#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
-#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
-#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
-#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
-#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
-#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
-#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
-#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
-#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
-#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
-#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
-#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
-#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
-#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
-#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
-#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
-#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
-#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
-#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
-#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
-#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
-#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
-#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
-#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
-#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
-#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
-#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
-#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
-#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
-#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
-#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
-#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
-
-#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
-#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
-#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
-#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
-
/*
* Module specific PRM register offsets from PRM_BASE + domain offset
*
@@ -200,66 +46,83 @@
#define PM_EVGENONTIM 0x00d8
#define PM_EVGENOFFTIM 0x00dc
-/* OMAP2xxx specific register offsets */
-#define OMAP24XX_PM_WKEN2 0x00a4
-#define OMAP24XX_PM_WKST2 0x00b4
-
-#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
-#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
-#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
-#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
-/* OMAP3 specific register offsets */
-#define OMAP3430ES2_PM_WKEN3 0x00f0
-#define OMAP3430ES2_PM_WKST3 0x00b8
-
-#define OMAP3430_PM_MPUGRPSEL 0x00a4
-#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
-#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
-
-#define OMAP3430_PM_IVAGRPSEL 0x00a8
-#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
-#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
-
-#define OMAP3430_PM_PREPWSTST 0x00e8
-
-#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
-#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#include "powerdomain.h"
-#ifndef __ASSEMBLER__
/* Power/reset management domain register get/set */
-extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
-extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx);
-extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
-extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
-extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
+{
+ return __raw_readl(prm_base + module + idx);
+}
+
+static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __raw_writel(val, prm_base + module + idx);
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
+ s16 idx)
+{
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ omap2_prm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(domain, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
/* These omap2_ PRM functions apply to both OMAP2 and 3 */
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);
-
-extern void omap3xxx_prm_reconfigure_io_chain(void);
-
-/* PRM interrupt-related functions */
-extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
-extern void omap3xxx_prm_ocp_barrier(void);
-extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
-extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
+extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
+extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+extern int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm);
+extern int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst);
+extern int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst);
+extern int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
+extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
+extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm);
+
+extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2);
+extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2);
+extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2);
+extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
#endif /* __ASSEMBLER */
@@ -348,7 +211,9 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
*
* 3430: RM_RSTST_CORE, RM_RSTST_EMU
*/
+#define OMAP_GLOBALWARM_RST_SHIFT 1
#define OMAP_GLOBALWARM_RST_MASK (1 << 1)
+#define OMAP_GLOBALCOLD_RST_SHIFT 0
#define OMAP_GLOBALCOLD_RST_MASK (1 << 0)
/*
@@ -376,11 +241,4 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
#define OMAP_LOGICRETSTATE_MASK (1 << 2)
-/*
- * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
- * submodule to exit hardreset
- */
-#define MAX_MODULE_HARDRESET_WAIT 10000
-
-
#endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 0d8abb577669..1ac73883f891 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include "common.h"
+#include "powerdomain.h"
#include "prm33xx.h"
#include "prm-regbits-33xx.h"
@@ -131,3 +132,204 @@ int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
+
+static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ return 0;
+}
+
+static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ v &= OMAP_POWERSTATE_MASK;
+ v >>= OMAP_POWERSTATE_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= OMAP_POWERSTATEST_MASK;
+ v >>= OMAP_POWERSTATEST_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
+ v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
+{
+ am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
+ (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ return 0;
+}
+
+static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
+ AM33XX_LASTPOWERSTATEENTERED_MASK,
+ pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ return 0;
+}
+
+static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 m;
+
+ m = pwrdm->logicretstate_mask;
+ if (!m)
+ return -EINVAL;
+
+ am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+
+ return 0;
+}
+
+static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= AM33XX_LOGICSTATEST_MASK;
+ v >>= AM33XX_LOGICSTATEST_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ u32 v, m;
+
+ m = pwrdm->logicretstate_mask;
+ if (!m)
+ return -EINVAL;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = pwrdm->mem_on_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+
+ return 0;
+}
+
+static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = pwrdm->mem_ret_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+
+ return 0;
+}
+
+static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = pwrdm->mem_pwrst_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = pwrdm->mem_retst_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
+ & OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ pr_err("powerdomain: %s: waited too long to complete transition\n",
+ pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+struct pwrdm_ops am33xx_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
+ .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
+ .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
+ .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
+ .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
+ .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
+};
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
new file mode 100644
index 000000000000..b86116cf0db9
--- /dev/null
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -0,0 +1,417 @@
+/*
+ * OMAP3xxx PRM module functions
+ *
+ * Copyright (C) 2010-2012 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * BenoƮt Cousson
+ * Paul Walmsley
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include "common.h"
+#include <plat/cpu.h>
+
+#include "vp.h"
+#include "powerdomain.h"
+#include "prm3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+
+static const struct omap_prcm_irq omap3_prcm_irqs[] = {
+ OMAP_PRCM_IRQ("wkup", 0, 0),
+ OMAP_PRCM_IRQ("io", 9, 1),
+};
+
+static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
+ .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+ .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
+ .nr_regs = 1,
+ .irqs = omap3_prcm_irqs,
+ .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
+ .irq = 11 + OMAP_INTC_START,
+ .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
+ .ocp_barrier = &omap3xxx_prm_ocp_barrier,
+ .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
+ .restore_irqen = &omap3xxx_prm_restore_irqen,
+};
+
+/*
+ * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware
+ * register (which are specific to OMAP3xxx SoCs) to reset source ID
+ * bit shifts (which is an OMAP SoC-independent enumeration)
+ */
+static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = {
+ { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
+ { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
+ { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
+ { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
+ { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT,
+ OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
+ { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT,
+ OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
+ { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
+ { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT },
+ { -1, -1 },
+};
+
+/* 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;
+};
+
+static 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);
+}
+
+/**
+ * omap3xxx_prm_dpll3_reset - use DPLL3 reset to reboot the OMAP SoC
+ *
+ * Set the DPLL3 reset bit, which should reboot the SoC. This is the
+ * recommended way to restart the SoC, considering Errata i520. No
+ * return value.
+ */
+void omap3xxx_prm_dpll3_reset(void)
+{
+ omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD,
+ OMAP2_RM_RSTCTRL);
+ /* OCP barrier */
+ omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL);
+}
+
+/**
+ * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
+ * @events: ptr to a u32, preallocated by caller
+ *
+ * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
+ * MPU IRQs, and store the result into the u32 pointed to by @events.
+ * No return value.
+ */
+void omap3xxx_prm_read_pending_irqs(unsigned long *events)
+{
+ u32 mask, st;
+
+ /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
+ mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+ events[0] = mask & st;
+}
+
+/**
+ * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
+ *
+ * Force any buffered writes to the PRM IP block to complete. Needed
+ * by the PRM IRQ handler, which reads and writes directly to the IP
+ * block, to avoid race conditions after acknowledging or clearing IRQ
+ * bits. No return value.
+ */
+void omap3xxx_prm_ocp_barrier(void)
+{
+ omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
+}
+
+/**
+ * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
+ * @saved_mask: ptr to a u32 array to save IRQENABLE bits
+ *
+ * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
+ * must be allocated by the caller. Intended to be used in the PRM
+ * interrupt handler suspend callback. The OCP barrier is needed to
+ * ensure the write to disable PRM interrupts reaches the PRM before
+ * returning; otherwise, spurious interrupts might occur. No return
+ * value.
+ */
+void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
+{
+ saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+
+ /* OCP barrier */
+ omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
+}
+
+/**
+ * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
+ * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
+ *
+ * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
+ * to be used in the PRM interrupt handler resume callback to restore
+ * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
+ * barrier should be needed here; any pending PRM interrupts will fire
+ * once the writes reach the PRM. No return value.
+ */
+void omap3xxx_prm_restore_irqen(u32 *saved_mask)
+{
+ omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
+ OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+}
+
+/**
+ * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
+ *
+ * Clear any previously-latched I/O wakeup events and ensure that the
+ * I/O wakeup gates are aligned with the current mux settings. Works
+ * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
+ * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
+ * return value.
+ */
+void omap3xxx_prm_reconfigure_io_chain(void)
+{
+ int i = 0;
+
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+
+ omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+ OMAP3430_ST_IO_CHAIN_MASK,
+ MAX_IOPAD_LATCH_TIME, i);
+ if (i == MAX_IOPAD_LATCH_TIME)
+ pr_warn("PRM: I/O chain clock line assertion timed out\n");
+
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKST);
+
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
+}
+
+/**
+ * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM. For I/O
+ * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
+ * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
+ * No return value.
+ */
+static void __init omap3xxx_prm_enable_io_wakeup(void)
+{
+ if (omap3_has_io_wakeup())
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+ PM_WKEN);
+}
+
+/**
+ * omap3xxx_prm_read_reset_sources - return the last SoC reset source
+ *
+ * Return a u32 representing the last reset sources of the SoC. The
+ * returned reset source bits are standardized across OMAP SoCs.
+ */
+static u32 omap3xxx_prm_read_reset_sources(void)
+{
+ struct prm_reset_src_map *p;
+ u32 r = 0;
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
+
+ p = omap3xxx_prm_reset_src_map;
+ while (p->reg_shift >= 0 && p->std_shift >= 0) {
+ if (v & (1 << p->reg_shift))
+ r |= 1 << p->std_shift;
+ p++;
+ }
+
+ return r;
+}
+
+/* Powerdomain low-level functions */
+
+/* Applicable only for OMAP3. Not supported on OMAP2 */
+static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTPOWERSTATEENTERED_MASK);
+}
+
+static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTLOGICSTATEENTERED_MASK);
+}
+
+static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP3430_LASTMEM1STATEENTERED_MASK;
+ case 1:
+ return OMAP3430_LASTMEM2STATEENTERED_MASK;
+ case 2:
+ return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
+ case 3:
+ return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap3_get_mem_bank_lastmemst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST, m);
+}
+
+static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
+ return 0;
+}
+
+static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return omap2_prm_rmw_mod_reg_bits(0,
+ 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+}
+
+static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ 0, pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+}
+
+struct pwrdm_ops omap3_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
+ .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
+ .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
+ .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
+ .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
+ .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
+ .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
+ .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
+ .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
+};
+
+/*
+ *
+ */
+
+static struct prm_ll_data omap3xxx_prm_ll_data = {
+ .read_reset_sources = &omap3xxx_prm_read_reset_sources,
+};
+
+static int __init omap3xxx_prm_init(void)
+{
+ int ret;
+
+ if (!cpu_is_omap34xx())
+ return 0;
+
+ ret = prm_register(&omap3xxx_prm_ll_data);
+ if (ret)
+ return ret;
+
+ omap3xxx_prm_enable_io_wakeup();
+ ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
+ if (!ret)
+ irq_set_status_flags(omap_prcm_event_to_irq("io"),
+ IRQ_NOAUTOEN);
+
+
+ return ret;
+}
+subsys_initcall(omap3xxx_prm_init);
+
+static void __exit omap3xxx_prm_exit(void)
+{
+ if (!cpu_is_omap34xx())
+ return;
+
+ /* Should never happen */
+ WARN(prm_unregister(&omap3xxx_prm_ll_data),
+ "%s: prm_ll_data function pointer mismatch\n", __func__);
+}
+__exitcall(omap3xxx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
new file mode 100644
index 000000000000..10cd41a8129e
--- /dev/null
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -0,0 +1,162 @@
+/*
+ * OMAP3xxx Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * The PRM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The PRM on OMAP4 has a new register layout, and is handled
+ * in a separate file.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM3XXX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm2xxx_3xxx.h"
+
+#define OMAP34XX_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP3-specific global PRM registers
+ * Use __raw_{read,write}l() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE
+ * bits.)
+ */
+
+#define OMAP3_PRM_REVISION_OFFSET 0x0004
+#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
+#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
+#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
+
+#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
+#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
+#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
+
+
+#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
+#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
+#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
+#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
+#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
+#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
+#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
+#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
+#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
+#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
+#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
+#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
+#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
+#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
+#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
+#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
+#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
+#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
+#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
+#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
+#define OMAP3_PRM_RSTST_OFFSET 0x0058
+#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
+#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
+#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
+#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
+#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
+#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
+#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
+#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
+#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
+#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
+#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
+#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
+#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
+#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
+#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
+#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
+#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
+#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
+#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
+#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
+#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
+#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
+#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
+#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
+#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
+#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
+#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
+#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
+#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
+#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
+#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
+#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
+#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
+#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
+#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
+#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
+#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
+#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
+#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
+#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
+#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
+
+#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
+#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
+#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/* OMAP3 specific register offsets */
+#define OMAP3430ES2_PM_WKEN3 0x00f0
+#define OMAP3430ES2_PM_WKST3 0x00b8
+
+#define OMAP3430_PM_MPUGRPSEL 0x00a4
+#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
+#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
+
+#define OMAP3430_PM_IVAGRPSEL 0x00a8
+#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
+#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
+
+#define OMAP3430_PM_PREPWSTST 0x00e8
+
+#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
+#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
+
+
+#ifndef __ASSEMBLER__
+
+/* 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);
+
+extern void omap3xxx_prm_reconfigure_io_chain(void);
+
+/* PRM interrupt-related functions */
+extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
+extern void omap3xxx_prm_ocp_barrier(void);
+extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
+extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
+
+extern void omap3xxx_prm_dpll3_reset(void);
+
+extern u32 omap3xxx_prm_get_reset_sources(void);
+
+#endif /* __ASSEMBLER */
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index f0c4d5f4a174..6d3467af205d 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -1,10 +1,11 @@
/*
* OMAP4 PRM module functions
*
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011-2012 Texas Instruments, Inc.
* Copyright (C) 2010 Nokia Corporation
* BenoƮt Cousson
* Paul Walmsley
+ * 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
@@ -17,7 +18,6 @@
#include <linux/err.h>
#include <linux/io.h>
-#include <plat/prcm.h>
#include "soc.h"
#include "iomap.h"
@@ -27,6 +27,9 @@
#include "prm-regbits-44xx.h"
#include "prcm44xx.h"
#include "prminst44xx.h"
+#include "powerdomain.h"
+
+/* Static data */
static const struct omap_prcm_irq omap4_prcm_irqs[] = {
OMAP_PRCM_IRQ("wkup", 0, 0),
@@ -46,6 +49,33 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
.restore_irqen = &omap44xx_prm_restore_irqen,
};
+/*
+ * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
+ * hardware register (which are specific to OMAP44xx SoCs) to reset
+ * source ID bit shifts (which is an OMAP SoC-independent
+ * enumeration)
+ */
+static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
+ { OMAP4430_RST_GLOBAL_WARM_SW_SHIFT,
+ OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
+ { OMAP4430_RST_GLOBAL_COLD_SW_SHIFT,
+ OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
+ { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT,
+ OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
+ { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
+ { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
+ { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT,
+ OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
+ { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT,
+ OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT },
+ { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT,
+ OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
+ { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
+ { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT },
+ { -1, -1 },
+};
+
/* PRM low-level functions */
/* Read a register in a CM/PRM instance in the PRM module */
@@ -291,12 +321,324 @@ static void __init omap44xx_prm_enable_io_wakeup(void)
OMAP4_PRM_IO_PMCTRL_OFFSET);
}
-static int __init omap4xxx_prcm_init(void)
+/**
+ * omap44xx_prm_read_reset_sources - return the last SoC reset source
+ *
+ * Return a u32 representing the last reset sources of the SoC. The
+ * returned reset source bits are standardized across OMAP SoCs.
+ */
+static u32 omap44xx_prm_read_reset_sources(void)
+{
+ struct prm_reset_src_map *p;
+ u32 r = 0;
+ u32 v;
+
+ v = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_RM_RSTST);
+
+ p = omap44xx_prm_reset_src_map;
+ while (p->reg_shift >= 0 && p->std_shift >= 0) {
+ if (v & (1 << p->reg_shift))
+ r |= 1 << p->std_shift;
+ p++;
+ }
+
+ return r;
+}
+
+/* Powerdomain low-level functions */
+
+static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= OMAP_POWERSTATE_MASK;
+ v >>= OMAP_POWERSTATE_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP_POWERSTATEST_MASK;
+ v >>= OMAP_POWERSTATEST_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
+ v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
+ (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
+ OMAP4430_LASTPOWERSTATEENTERED_MASK,
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTST);
+ return 0;
+}
+
+static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 v;
+
+ v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
+
+ omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP4430_LOGICSTATEST_MASK;
+ v >>= OMAP4430_LOGICSTATEST_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
{
- if (cpu_is_omap44xx()) {
- omap44xx_prm_enable_io_wakeup();
- return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= OMAP4430_LOGICRETSTATE_MASK;
+ v >>= OMAP4430_LOGICRETSTATE_SHIFT;
+
+ return v;
+}
+
+/**
+ * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
+ * @pwrdm: struct powerdomain * to read the state for
+ *
+ * Reads the previous logic powerstate for a powerdomain. This
+ * function must determine the previous logic powerstate by first
+ * checking the previous powerstate for the domain. If that was OFF,
+ * then logic has been lost. If previous state was RETENTION, the
+ * function reads the setting for the next retention logic state to
+ * see the actual value. In every other case, the logic is
+ * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
+ * depending whether the logic was retained or not.
+ */
+static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ int state;
+
+ state = omap4_pwrdm_read_prev_pwrst(pwrdm);
+
+ if (state == PWRDM_POWER_OFF)
+ return PWRDM_POWER_OFF;
+
+ if (state != PWRDM_POWER_RET)
+ return PWRDM_POWER_RET;
+
+ return omap4_pwrdm_read_logic_retst(pwrdm);
+}
+
+static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+/**
+ * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
+ * @pwrdm: struct powerdomain * to read mem powerstate for
+ * @bank: memory bank index
+ *
+ * Reads the previous memory powerstate for a powerdomain. This
+ * function must determine the previous memory powerstate by first
+ * checking the previous powerstate for the domain. If that was OFF,
+ * then logic has been lost. If previous state was RETENTION, the
+ * function reads the setting for the next memory retention state to
+ * see the actual value. In every other case, the logic is
+ * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
+ * depending whether logic was retained or not.
+ */
+static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ int state;
+
+ state = omap4_pwrdm_read_prev_pwrst(pwrdm);
+
+ if (state == PWRDM_POWER_OFF)
+ return PWRDM_POWER_OFF;
+
+ if (state != PWRDM_POWER_RET)
+ return PWRDM_POWER_RET;
+
+ return omap4_pwrdm_read_mem_retst(pwrdm, bank);
+}
+
+static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
+ pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST) &
+ OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ pr_err("powerdomain: %s: waited too long to complete transition\n",
+ pwrdm->name);
+ return -EAGAIN;
}
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
return 0;
}
-subsys_initcall(omap4xxx_prcm_init);
+
+struct pwrdm_ops omap4_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
+ .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
+ .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
+ .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst,
+ .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
+ .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
+ .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
+ .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
+ .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
+};
+
+/*
+ * XXX document
+ */
+static struct prm_ll_data omap44xx_prm_ll_data = {
+ .read_reset_sources = &omap44xx_prm_read_reset_sources,
+};
+
+static int __init omap44xx_prm_init(void)
+{
+ int ret;
+
+ if (!cpu_is_omap44xx())
+ return 0;
+
+ ret = prm_register(&omap44xx_prm_ll_data);
+ if (ret)
+ return ret;
+
+ omap44xx_prm_enable_io_wakeup();
+
+ return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+}
+subsys_initcall(omap44xx_prm_init);
+
+static void __exit omap44xx_prm_exit(void)
+{
+ if (!cpu_is_omap44xx())
+ return;
+
+ /* Should never happen */
+ WARN(prm_unregister(&omap44xx_prm_ll_data),
+ "%s: prm_ll_data function pointer mismatch\n", __func__);
+}
+__exitcall(omap44xx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index ee72ae6bd8c9..c8e1accdc90e 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -771,6 +771,8 @@ extern void omap44xx_prm_ocp_barrier(void);
extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
+extern u32 omap44xx_prm_get_reset_sources(void);
+
# endif
#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 3442227d3f0b..f596e1e91ffd 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -24,10 +24,11 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
-#include <plat/prcm.h>
-
#include "prm2xxx_3xxx.h"
+#include "prm2xxx.h"
+#include "prm3xxx.h"
#include "prm44xx.h"
+#include "common.h"
/*
* OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
@@ -52,6 +53,16 @@ static struct irq_chip_generic **prcm_irq_chips;
*/
static struct omap_prcm_irq_setup *prcm_irq_setup;
+/* prm_base: base virtual address of the PRM IP block */
+void __iomem *prm_base;
+
+/*
+ * prm_ll_data: function pointers to SoC-specific implementations of
+ * common PRM functions
+ */
+static struct prm_ll_data null_prm_ll_data;
+static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;
+
/* Private functions */
/*
@@ -318,64 +329,82 @@ err:
return -ENOMEM;
}
-/*
- * Stubbed functions so that common files continue to build when
- * custom builds are used
- * XXX These are temporary and should be removed at the earliest possible
- * opportunity
+/**
+ * omap2_set_globals_prm - set the PRM base address (for early use)
+ * @prm: PRM base virtual address
+ *
+ * XXX Will be replaced when the PRM/CM drivers are completed.
*/
-u32 __weak omap2_prm_read_mod_reg(s16 module, u16 idx)
+void __init omap2_set_globals_prm(void __iomem *prm)
{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
- return 0;
+ prm_base = prm;
}
-void __weak omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+/**
+ * prm_read_reset_sources - return the sources of the SoC's last reset
+ *
+ * Return a u32 bitmask representing the reset sources that caused the
+ * SoC to reset. The low-level per-SoC functions called by this
+ * function remap the SoC-specific reset source bits into an
+ * OMAP-common set of reset source bits, defined in
+ * arch/arm/mach-omap2/prm.h. Returns the standardized reset source
+ * u32 bitmask from the hardware upon success, or returns (1 <<
+ * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
+ * function was registered.
+ */
+u32 prm_read_reset_sources(void)
{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
-}
+ u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;
-u32 __weak omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits,
- s16 module, s16 idx)
-{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
- return 0;
-}
+ if (prm_ll_data->read_reset_sources)
+ ret = prm_ll_data->read_reset_sources();
+ else
+ WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);
-u32 __weak omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
- return 0;
+ return ret;
}
-u32 __weak omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+/**
+ * prm_register - register per-SoC low-level data with the PRM
+ * @pld: low-level per-SoC OMAP PRM data & function pointers to register
+ *
+ * Register per-SoC low-level OMAP PRM data and function pointers with
+ * the OMAP PRM common interface. The caller must keep the data
+ * pointed to by @pld valid until it calls prm_unregister() and
+ * it returns successfully. Returns 0 upon success, -EINVAL if @pld
+ * is NULL, or -EEXIST if prm_register() has already been called
+ * without an intervening prm_unregister().
+ */
+int prm_register(struct prm_ll_data *pld)
{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
- return 0;
-}
+ if (!pld)
+ return -EINVAL;
-u32 __weak omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
-{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
- return 0;
-}
+ if (prm_ll_data != &null_prm_ll_data)
+ return -EEXIST;
-int __weak omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
-{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
- return 0;
-}
+ prm_ll_data = pld;
-int __weak omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
-{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
return 0;
}
-int __weak omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
- u8 st_shift)
+/**
+ * prm_unregister - unregister per-SoC low-level data & function pointers
+ * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
+ *
+ * Unregister per-SoC low-level OMAP PRM data and function pointers
+ * that were previously registered with prm_register(). The
+ * caller may not destroy any of the data pointed to by @pld until
+ * this function returns successfully. Returns 0 upon success, or
+ * -EINVAL if @pld is NULL or if @pld does not match the struct
+ * prm_ll_data * previously registered by prm_register().
+ */
+int prm_unregister(struct prm_ll_data *pld)
{
- WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
+ if (!pld || prm_ll_data != pld)
+ return -EINVAL;
+
+ prm_ll_data = &null_prm_ll_data;
+
return 0;
}
-
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h
index 46f2efb36596..a2ede2d65481 100644
--- a/arch/arm/mach-omap2/prminst44xx.h
+++ b/arch/arm/mach-omap2/prminst44xx.h
@@ -30,4 +30,6 @@ extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs);
+extern void omap_prm_base_init(void);
+
#endif
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index c64ee1904be8..dae7e4804a48 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -112,12 +112,10 @@ int omap2_sdrc_get_params(unsigned long r,
}
-void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
+void __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms)
{
- if (omap2_globals->sdrc)
- omap2_sdrc_base = omap2_globals->sdrc;
- if (omap2_globals->sms)
- omap2_sms_base = omap2_globals->sms;
+ omap2_sdrc_base = sdrc;
+ omap2_sms_base = sms;
}
/**
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
index 69c4b329452e..446aa13511fd 100644
--- a/arch/arm/mach-omap2/sdrc.h
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -51,6 +51,8 @@ static inline u32 sms_read_reg(u16 reg)
return __raw_readl(OMAP_SMS_REGADDR(reg));
}
+extern void omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms);
+
/**
* struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
index 20cc950db4de..907291714643 100644
--- a/arch/arm/mach-omap2/sdrc2xxx.c
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -27,7 +27,7 @@
#include "soc.h"
#include "iomap.h"
#include "common.h"
-#include "prm2xxx_3xxx.h"
+#include "prm2xxx.h"
#include "clock.h"
#include "sdrc.h"
#include "sram.h"
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 7046c3c67181..d1dedc8195ed 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -28,8 +28,8 @@
#include "omap34xx.h"
#include "iomap.h"
-#include "cm2xxx_3xxx.h"
-#include "prm2xxx_3xxx.h"
+#include "cm3xxx.h"
+#include "prm3xxx.h"
#include "sdrc.h"
#include "sram.h"
#include "control.h"
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
index 8f7326cd435b..680a7c56cc3e 100644
--- a/arch/arm/mach-omap2/sram242x.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -34,8 +34,8 @@
#include "soc.h"
#include "iomap.h"
-#include "prm2xxx_3xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "prm2xxx.h"
+#include "cm2xxx.h"
#include "sdrc.h"
.text
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
index b140d6578529..a1e9edd673f4 100644
--- a/arch/arm/mach-omap2/sram243x.S
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -34,8 +34,8 @@
#include "soc.h"
#include "iomap.h"
-#include "prm2xxx_3xxx.h"
-#include "cm2xxx_3xxx.h"
+#include "prm2xxx.h"
+#include "cm2xxx.h"
#include "sdrc.h"
.text
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 2d0ceaa23fb8..1446331b576a 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -32,7 +32,7 @@
#include "soc.h"
#include "iomap.h"
#include "sdrc.h"
-#include "cm2xxx_3xxx.h"
+#include "cm3xxx.h"
/*
* This file needs be built unconditionally as ARM to interoperate correctly
diff --git a/arch/arm/mach-omap2/ti81xx.h b/arch/arm/mach-omap2/ti81xx.h
index 8f9843f78422..a1e6caf0dba6 100644
--- a/arch/arm/mach-omap2/ti81xx.h
+++ b/arch/arm/mach-omap2/ti81xx.h
@@ -22,6 +22,15 @@
#define TI81XX_CTRL_BASE TI81XX_SCM_BASE
#define TI81XX_PRCM_BASE 0x48180000
+/*
+ * Adjust TAP register base such that omap3_check_revision accesses the correct
+ * TI81XX register for checking device ID (it adds 0x204 to tap base while
+ * TI81XX DEVICE ID register is at offset 0x600 from control base).
+ */
+#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \
+ TI81XX_CONTROL_DEVICE_ID - 0x204)
+
+
#define TI81XX_ARM_INTC_BASE 0x48200000
#endif /* __ASM_ARCH_TI81XX_H */
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
index f6b6c37ac3f4..7c2b4ed38f02 100644
--- a/arch/arm/mach-omap2/wd_timer.c
+++ b/arch/arm/mach-omap2/wd_timer.c
@@ -1,6 +1,8 @@
/*
* OMAP2+ MPU WD_TIMER-specific code
*
+ * Copyright (C) 2012 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 as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -11,10 +13,14 @@
#include <linux/io.h>
#include <linux/err.h>
-#include "omap_hwmod.h"
+#include <linux/platform_data/omap-wd-timer.h>
+#include "omap_hwmod.h"
+#include "omap_device.h"
#include "wd_timer.h"
#include "common.h"
+#include "prm.h"
+#include "soc.h"
/*
* In order to avoid any assumptions from bootloader regarding WDT
@@ -26,9 +32,6 @@
#define OMAP_WDT_WPS 0x34
#define OMAP_WDT_SPR 0x48
-/* Maximum microseconds to wait for OMAP module to softreset */
-#define MAX_MODULE_SOFTRESET_WAIT 10000
-
int omap2_wd_timer_disable(struct omap_hwmod *oh)
{
void __iomem *base;
@@ -99,3 +102,32 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh)
return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT :
omap2_wd_timer_disable(oh);
}
+
+static int __init omap_init_wdt(void)
+{
+ int id = -1;
+ struct platform_device *pdev;
+ struct omap_hwmod *oh;
+ char *oh_name = "wd_timer2";
+ char *dev_name = "omap_wdt";
+ struct omap_wd_timer_platform_data pdata;
+
+ if (!cpu_class_is_omap2() || of_have_populated_dt())
+ return 0;
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up wd_timer%d hwmod\n", id);
+ return -EINVAL;
+ }
+
+ pdata.read_reset_sources = prm_read_reset_sources;
+
+ pdev = omap_device_build(dev_name, id, oh, &pdata,
+ sizeof(struct omap_wd_timer_platform_data),
+ NULL, 0, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
+ dev_name, oh->name);
+ return 0;
+}
+subsys_initcall(omap_init_wdt);
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
deleted file mode 100644
index 267f43bb2a4e..000000000000
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/prcm.h
- *
- * Access definations for use in OMAP24XX clock and power management
- *
- * Copyright (C) 2005 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 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
- *
- * XXX This file is deprecated. The PRCM is an OMAP2+-only subsystem,
- * so this file doesn't belong in plat-omap/include/plat. Please
- * do not add anything new to this file.
- */
-
-#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
-#define __ASM_ARM_ARCH_OMAP_PRCM_H
-
-u32 omap_prcm_get_reset_sources(void);
-int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
- const char *name);
-
-#endif
-
-
-
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index f5db18dbc0f9..477a1d47a64c 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -46,8 +46,8 @@
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <mach/hardware.h>
-#include <plat/cpu.h>
-#include <plat/prcm.h>
+
+#include <linux/platform_data/omap-wd-timer.h>
#include "omap_wdt.h"
@@ -202,8 +202,10 @@ static ssize_t omap_wdt_write(struct file *file, const char __user *data,
static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ struct omap_wd_timer_platform_data *pdata;
struct omap_wdt_dev *wdev;
- int new_margin;
+ u32 rs;
+ int new_margin, bs;
static const struct watchdog_info ident = {
.identity = "OMAP Watchdog",
.options = WDIOF_SETTIMEOUT,
@@ -211,6 +213,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
};
wdev = file->private_data;
+ pdata = wdev->dev->platform_data;
switch (cmd) {
case WDIOC_GETSUPPORT:
@@ -219,17 +222,12 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
case WDIOC_GETSTATUS:
return put_user(0, (int __user *)arg);
case WDIOC_GETBOOTSTATUS:
-#ifdef CONFIG_ARCH_OMAP1
- if (cpu_is_omap16xx())
- return put_user(__raw_readw(ARM_SYSST),
- (int __user *)arg);
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
- if (cpu_is_omap24xx())
- return put_user(omap_prcm_get_reset_sources(),
- (int __user *)arg);
-#endif
- return put_user(0, (int __user *)arg);
+ if (!pdata || !pdata->read_reset_sources)
+ return put_user(0, (int __user *)arg);
+ rs = pdata->read_reset_sources();
+ bs = (rs & (1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT)) ?
+ WDIOF_CARDRESET : 0;
+ return put_user(bs, (int __user *)arg);
case WDIOC_KEEPALIVE:
spin_lock(&wdt_lock);
omap_wdt_ping(wdev);
diff --git a/include/linux/platform_data/omap-wd-timer.h b/include/linux/platform_data/omap-wd-timer.h
new file mode 100644
index 000000000000..d75f5f802d98
--- /dev/null
+++ b/include/linux/platform_data/omap-wd-timer.h
@@ -0,0 +1,38 @@
+/*
+ * OMAP2+ WDTIMER-specific function prototypes
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_OMAP_WD_TIMER_H
+#define __LINUX_PLATFORM_DATA_OMAP_WD_TIMER_H
+
+#include <linux/types.h>
+
+/*
+ * Standardized OMAP reset source bits
+ *
+ * This is a subset of the ones listed in arch/arm/mach-omap2/prm.h
+ * and are the only ones needed in the watchdog driver.
+ */
+#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
+
+/**
+ * struct omap_wd_timer_platform_data - WDTIMER integration to the host SoC
+ * @read_reset_sources - fn ptr for the SoC to indicate the last reset cause
+ *
+ * The function pointed to by @read_reset_sources must return its data
+ * in a standard format - search for RST_SRC_ID_SHIFT in
+ * arch/arm/mach-omap2
+ */
+struct omap_wd_timer_platform_data {
+ u32 (*read_reset_sources)(void);
+};
+
+#endif