aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap1/common.h2
-rw-r--r--arch/arm/mach-omap1/reset.c38
-rw-r--r--arch/arm/mach-omap2/Makefile110
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c2
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpll.c2
-rw-r--r--arch/arm/mach-omap2/clock.c3
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c2
-rw-r--r--arch/arm/mach-omap2/clock2430.c2
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c2
-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.h12
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c255
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h66
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h119
-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)307
-rw-r--r--arch/arm/mach-omap2/cm3xxx.h86
-rw-r--r--arch/arm/mach-omap2/cm_common.c71
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c142
-rw-r--r--arch/arm/mach-omap2/control.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c51
-rw-r--r--arch/arm/mach-omap2/pm24xx.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c5
-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/prm-regbits-24xx.h6
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h12
-rw-r--r--arch/arm/mach-omap2/prm.h53
-rw-r--r--arch/arm/mach-omap2/prm2xxx.c126
-rw-r--r--arch/arm/mach-omap2/prm2xxx.h132
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c332
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h277
-rw-r--r--arch/arm/mach-omap2/prm33xx.c202
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c403
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h160
-rw-r--r--arch/arm/mach-omap2/prm44xx.c355
-rw-r--r--arch/arm/mach-omap2/prm44xx.h2
-rw-r--r--arch/arm/mach-omap2/prm_common.c104
-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
49 files changed, 2750 insertions, 2099 deletions
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index 26e19d3b7924..d6ac18d04da7 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -94,4 +94,6 @@ extern int ocpi_enable(void);
94static inline int ocpi_enable(void) { return 0; } 94static inline int ocpi_enable(void) { return 0; }
95#endif 95#endif
96 96
97extern int omap1_get_reset_sources(void);
98
97#endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */ 99#endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */
diff --git a/arch/arm/mach-omap1/reset.c b/arch/arm/mach-omap1/reset.c
index b17709103866..a0a9f97772ea 100644
--- a/arch/arm/mach-omap1/reset.c
+++ b/arch/arm/mach-omap1/reset.c
@@ -10,6 +10,19 @@
10 10
11#include "common.h" 11#include "common.h"
12 12
13/* ARM_SYSST bit shifts related to SoC reset sources */
14#define ARM_SYSST_POR_SHIFT 5
15#define ARM_SYSST_EXT_RST_SHIFT 4
16#define ARM_SYSST_ARM_WDRST_SHIFT 2
17#define ARM_SYSST_GLOB_SWRST_SHIFT 1
18
19/* Standardized reset source bits (across all OMAP SoCs) */
20#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
21#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
22#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
23#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
24
25
13void omap1_restart(char mode, const char *cmd) 26void omap1_restart(char mode, const char *cmd)
14{ 27{
15 /* 28 /*
@@ -23,3 +36,28 @@ void omap1_restart(char mode, const char *cmd)
23 36
24 omap_writew(1, ARM_RSTCT1); 37 omap_writew(1, ARM_RSTCT1);
25} 38}
39
40/**
41 * omap1_get_reset_sources - return the source of the SoC's last reset
42 *
43 * Returns bits that represent the last reset source for the SoC. The
44 * format is standardized across OMAPs for use by the OMAP watchdog.
45 */
46int omap1_get_reset_sources(void)
47{
48 int ret = 0;
49 u16 rs;
50
51 rs = __raw_readw(ARM_SYSST);
52
53 if (rs & (1 << ARM_SYSST_POR_SHIFT))
54 ret |= 1 << OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT;
55 if (rs & (1 << ARM_SYSST_EXT_RST_SHIFT))
56 ret |= 1 << OMAP_EXTWARM_RST_SRC_ID_SHIFT;
57 if (rs & (1 << ARM_SYSST_ARM_WDRST_SHIFT))
58 ret |= 1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT;
59 if (rs & (1 << ARM_SYSST_GLOB_SWRST_SHIFT))
60 ret |= 1 << OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT;
61
62 return ret;
63}
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 46d9071f0938..ae87a3ea53ae 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 \
7 common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ 7 common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
8 omap_device.o 8 omap_device.o
9 9
10# INTCPS IP block support - XXX should be moved to drivers/ 10omap-2-3-common = irq.o
11obj-$(CONFIG_ARCH_OMAP2) += irq.o 11hwmod-common = omap_hwmod.o \
12obj-$(CONFIG_ARCH_OMAP3) += irq.o 12 omap_hwmod_common_data.o
13obj-$(CONFIG_SOC_AM33XX) += irq.o 13clock-common = clock.o clock_common_data.o \
14 14 clkt_dpll.o clkt_clksel.o
15# Secure monitor API support 15secure-common = omap-smc.o omap-secure.o
16obj-$(CONFIG_ARCH_OMAP3) += omap-smc.o omap-secure.o 16
17obj-$(CONFIG_ARCH_OMAP4) += omap-smc.o omap-secure.o 17obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
18obj-$(CONFIG_SOC_OMAP5) += omap-smc.o omap-secure.o 18obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
19obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
20obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
21obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common)
19 22
20ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) 23ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
21obj-y += mcbsp.o 24obj-y += mcbsp.o
22endif 25endif
23 26
24obj-$(CONFIG_TWL4030_CORE) += omap_twl.o 27obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
28obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
25 29
26# SMP support ONLY available for OMAP4 30# SMP support ONLY available for OMAP4
27 31
28obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o 32obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
29obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o 33obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
30obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o 34omap-4-5-common = omap4-common.o omap-wakeupgen.o \
31obj-$(CONFIG_SOC_OMAP5) += omap4-common.o omap-wakeupgen.o 35 sleep44xx.o
36obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common)
37obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common)
32 38
33plus_sec := $(call as-instr,.arch_extension sec,+sec) 39plus_sec := $(call as-instr,.arch_extension sec,+sec)
34AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) 40AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -53,7 +59,6 @@ obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
53# SMS/SDRC 59# SMS/SDRC
54obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o 60obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
55# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o 61# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
56obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
57 62
58# OPP table initialization 63# OPP table initialization
59ifeq ($(CONFIG_PM_OPP),y) 64ifeq ($(CONFIG_PM_OPP),y)
@@ -64,15 +69,15 @@ endif
64 69
65# Power Management 70# Power Management
66ifeq ($(CONFIG_PM),y) 71ifeq ($(CONFIG_PM),y)
67obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o sleep24xx.o 72obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
73obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
68obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o 74obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
69obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o 75obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
70obj-$(CONFIG_ARCH_OMAP4) += sleep44xx.o 76obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o
71obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o sleep44xx.o
72obj-$(CONFIG_PM_DEBUG) += pm-debug.o 77obj-$(CONFIG_PM_DEBUG) += pm-debug.o
73 78
74obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o 79obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
75obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o 80obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
76 81
77AFLAGS_sleep24xx.o :=-Wa,-march=armv6 82AFLAGS_sleep24xx.o :=-Wa,-march=armv6
78AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) 83AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -84,76 +89,82 @@ endif
84endif 89endif
85 90
86ifeq ($(CONFIG_CPU_IDLE),y) 91ifeq ($(CONFIG_CPU_IDLE),y)
87obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o 92obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
88obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o 93obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
89endif 94endif
90 95
91# PRCM 96# PRCM
92obj-y += prcm.o prm_common.o 97obj-y += prcm.o prm_common.o cm_common.o
93obj-$(CONFIG_ARCH_OMAP2) += cm2xxx_3xxx.o prm2xxx_3xxx.o 98obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
94obj-$(CONFIG_ARCH_OMAP3) += cm2xxx_3xxx.o prm2xxx_3xxx.o 99obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
95obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o 100obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
96obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o 101obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o
97omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ 102omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \
98 prcm_mpu44xx.o prminst44xx.o \ 103 prcm_mpu44xx.o prminst44xx.o \
99 vc44xx_data.o vp44xx_data.o \ 104 vc44xx_data.o vp44xx_data.o
100 prm44xx.o
101obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) 105obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
102obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common) 106obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common)
103 107
104# OMAP voltage domains 108# OMAP voltage domains
105obj-y += voltage.o vc.o vp.o 109voltagedomain-common := voltage.o vc.o vp.o
110obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
106obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o 111obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o
112obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common)
107obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o 113obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o
114obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common)
108obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o 115obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o
109obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o 116obj-$(CONFIG_SOC_AM33XX) += $(voltagedomain-common)
117obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o
118obj-$(CONFIG_SOC_OMAP5) += $(voltagedomain-common)
110 119
111# OMAP powerdomain framework 120# OMAP powerdomain framework
112obj-y += powerdomain.o powerdomain-common.o 121powerdomain-common += powerdomain.o powerdomain-common.o
122obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common)
113obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o 123obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o
114obj-$(CONFIG_ARCH_OMAP2) += powerdomain2xxx_3xxx.o
115obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o 124obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o
116obj-$(CONFIG_ARCH_OMAP3) += powerdomain2xxx_3xxx.o 125obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common)
117obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o 126obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o
118obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o 127obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
119obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o 128obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
120obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o 129obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
121obj-$(CONFIG_SOC_AM33XX) += powerdomain33xx.o 130obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common)
122obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o 131obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o
123obj-$(CONFIG_SOC_OMAP5) += powerdomain44xx.o 132obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common)
124 133
125# PRCM clockdomain control 134# PRCM clockdomain control
126obj-y += clockdomain.o 135clockdomain-common += clockdomain.o
127obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o 136obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common)
128obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o 137obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o
129obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o 138obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
130obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o 139obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
131obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o 140obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common)
132obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o 141obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o
133obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o 142obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o
134obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o 143obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
135obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o 144obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
136obj-$(CONFIG_SOC_AM33XX) += clockdomain33xx.o 145obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common)
137obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o 146obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o
138obj-$(CONFIG_SOC_OMAP5) += clockdomain44xx.o 147obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common)
139 148
140# Clock framework 149# Clock framework
141obj-y += clock.o clock_common_data.o \ 150obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
142 clkt_dpll.o clkt_clksel.o 151obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o
143obj-$(CONFIG_ARCH_OMAP2) += clock2xxx.o 152obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
144obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o clkt2xxx_sys.o
145obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o 153obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
146obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o 154obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
147obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o 155obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
148obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o 156obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
149obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o 157obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
150obj-$(CONFIG_ARCH_OMAP3) += clock3xxx.o 158obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
151obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o 159obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
152obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o clkt_iclk.o 160obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
153obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o 161obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
154obj-$(CONFIG_ARCH_OMAP4) += clock44xx_data.o 162obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
163obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o
155obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o 164obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
156obj-$(CONFIG_SOC_AM33XX) += dpll3xxx.o clock33xx_data.o 165obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o
166obj-$(CONFIG_SOC_AM33XX) += clock33xx_data.o
167obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
157obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o 168obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
158 169
159# OMAP2 clock rate set data (old "OPP" data) 170# OMAP2 clock rate set data (old "OPP" data)
@@ -161,7 +172,6 @@ obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
161obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o 172obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
162 173
163# hwmod data 174# hwmod data
164obj-y += omap_hwmod_common_data.o
165obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o 175obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o
166obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o 176obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o
167obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o 177obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o
@@ -207,10 +217,10 @@ obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
207obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o 217obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
208obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o 218obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
209obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o 219obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
210obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o 220obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
211obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o 221obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
212obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o 222obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
213obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o 223obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
214obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o 224obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o
215obj-$(CONFIG_MACH_OVERO) += board-overo.o 225obj-$(CONFIG_MACH_OVERO) += board-overo.o
216obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o 226obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index 73a1414b89b0..e3f0c1e262a7 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -25,7 +25,7 @@
25 25
26#include "clock.h" 26#include "clock.h"
27#include "clock2xxx.h" 27#include "clock2xxx.h"
28#include "cm2xxx_3xxx.h" 28#include "cm2xxx.h"
29#include "cm-regbits-24xx.h" 29#include "cm-regbits-24xx.h"
30 30
31/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */ 31/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
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 @@
15#include <linux/io.h> 15#include <linux/io.h>
16 16
17#include "clock.h" 17#include "clock.h"
18#include "cm2xxx_3xxx.h" 18#include "cm2xxx.h"
19#include "cm-regbits-24xx.h" 19#include "cm-regbits-24xx.h"
20 20
21/* Private functions */ 21/* Private functions */
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 8b30759f8f9e..9205ea7d8dde 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -33,7 +33,8 @@
33#include "soc.h" 33#include "soc.h"
34#include "clockdomain.h" 34#include "clockdomain.h"
35#include "clock.h" 35#include "clock.h"
36#include "cm2xxx_3xxx.h" 36#include "cm2xxx.h"
37#include "cm3xxx.h"
37#include "cm-regbits-24xx.h" 38#include "cm-regbits-24xx.h"
38#include "cm-regbits-34xx.h" 39#include "cm-regbits-34xx.h"
39 40
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index ff47a6c2611d..da1e388f22f7 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -23,7 +23,7 @@
23#include "clock.h" 23#include "clock.h"
24#include "clock2xxx.h" 24#include "clock2xxx.h"
25#include "opp2xxx.h" 25#include "opp2xxx.h"
26#include "cm2xxx_3xxx.h" 26#include "cm2xxx.h"
27#include "prm2xxx_3xxx.h" 27#include "prm2xxx_3xxx.h"
28#include "prm-regbits-24xx.h" 28#include "prm-regbits-24xx.h"
29#include "cm-regbits-24xx.h" 29#include "cm-regbits-24xx.h"
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 @@
25#include "iomap.h" 25#include "iomap.h"
26#include "clock.h" 26#include "clock.h"
27#include "clock2xxx.h" 27#include "clock2xxx.h"
28#include "cm2xxx_3xxx.h" 28#include "cm2xxx.h"
29#include "cm-regbits-24xx.h" 29#include "cm-regbits-24xx.h"
30 30
31/** 31/**
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index cab8e9c52d6e..c97dafef894d 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -22,7 +22,7 @@
22#include "clock.h" 22#include "clock.h"
23#include "clock2xxx.h" 23#include "clock2xxx.h"
24#include "opp2xxx.h" 24#include "opp2xxx.h"
25#include "cm2xxx_3xxx.h" 25#include "cm2xxx.h"
26#include "prm2xxx_3xxx.h" 26#include "prm2xxx_3xxx.h"
27#include "prm-regbits-24xx.h" 27#include "prm-regbits-24xx.h"
28#include "cm-regbits-24xx.h" 28#include "cm-regbits-24xx.h"
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 @@
23 23
24#include "clock.h" 24#include "clock.h"
25#include "clock34xx.h" 25#include "clock34xx.h"
26#include "cm2xxx_3xxx.h" 26#include "cm3xxx.h"
27#include "cm-regbits-34xx.h" 27#include "cm-regbits-34xx.h"
28 28
29/** 29/**
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 @@
23 23
24#include "clock.h" 24#include "clock.h"
25#include "clock3517.h" 25#include "clock3517.h"
26#include "cm2xxx_3xxx.h" 26#include "cm3xxx.h"
27#include "cm-regbits-34xx.h" 27#include "cm-regbits-34xx.h"
28 28
29/* 29/*
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 @@
28#include "clock34xx.h" 28#include "clock34xx.h"
29#include "clock36xx.h" 29#include "clock36xx.h"
30#include "clock3517.h" 30#include "clock3517.h"
31#include "cm2xxx_3xxx.h" 31#include "cm3xxx.h"
32#include "cm-regbits-34xx.h" 32#include "cm-regbits-34xx.h"
33#include "prm2xxx_3xxx.h" 33#include "prm2xxx_3xxx.h"
34#include "prm-regbits-34xx.h" 34#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 @@
1/*
2 * OMAP2 and OMAP3 clockdomain control
3 *
4 * Copyright (C) 2008-2010 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation
6 *
7 * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/types.h>
16#include <plat/prcm.h>
17
18#include "soc.h"
19#include "prm.h"
20#include "prm2xxx_3xxx.h"
21#include "cm.h"
22#include "cm2xxx_3xxx.h"
23#include "cm-regbits-24xx.h"
24#include "cm-regbits-34xx.h"
25#include "prm-regbits-24xx.h"
26#include "clockdomain.h"
27
28static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
29 struct clockdomain *clkdm2)
30{
31 omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
32 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
33 return 0;
34}
35
36static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
37 struct clockdomain *clkdm2)
38{
39 omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
40 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
41 return 0;
42}
43
44static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
45 struct clockdomain *clkdm2)
46{
47 return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
48 PM_WKDEP, (1 << clkdm2->dep_bit));
49}
50
51static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
52{
53 struct clkdm_dep *cd;
54 u32 mask = 0;
55
56 for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
57 if (!cd->clkdm)
58 continue; /* only happens if data is erroneous */
59
60 /* PRM accesses are slow, so minimize them */
61 mask |= 1 << cd->clkdm->dep_bit;
62 atomic_set(&cd->wkdep_usecount, 0);
63 }
64
65 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
66 PM_WKDEP);
67 return 0;
68}
69
70static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
71 struct clockdomain *clkdm2)
72{
73 omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
74 clkdm1->pwrdm.ptr->prcm_offs,
75 OMAP3430_CM_SLEEPDEP);
76 return 0;
77}
78
79static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
80 struct clockdomain *clkdm2)
81{
82 omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
83 clkdm1->pwrdm.ptr->prcm_offs,
84 OMAP3430_CM_SLEEPDEP);
85 return 0;
86}
87
88static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
89 struct clockdomain *clkdm2)
90{
91 return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
92 OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
93}
94
95static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
96{
97 struct clkdm_dep *cd;
98 u32 mask = 0;
99
100 for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
101 if (!cd->clkdm)
102 continue; /* only happens if data is erroneous */
103
104 /* PRM accesses are slow, so minimize them */
105 mask |= 1 << cd->clkdm->dep_bit;
106 atomic_set(&cd->sleepdep_usecount, 0);
107 }
108 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
109 OMAP3430_CM_SLEEPDEP);
110 return 0;
111}
112
113static int omap2_clkdm_sleep(struct clockdomain *clkdm)
114{
115 omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
116 clkdm->pwrdm.ptr->prcm_offs,
117 OMAP2_PM_PWSTCTRL);
118 return 0;
119}
120
121static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
122{
123 omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
124 clkdm->pwrdm.ptr->prcm_offs,
125 OMAP2_PM_PWSTCTRL);
126 return 0;
127}
128
129static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
130{
131 if (atomic_read(&clkdm->usecount) > 0)
132 _clkdm_add_autodeps(clkdm);
133
134 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
135 clkdm->clktrctrl_mask);
136}
137
138static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
139{
140 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
141 clkdm->clktrctrl_mask);
142
143 if (atomic_read(&clkdm->usecount) > 0)
144 _clkdm_del_autodeps(clkdm);
145}
146
147static void _enable_hwsup(struct clockdomain *clkdm)
148{
149 if (cpu_is_omap24xx())
150 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
151 clkdm->clktrctrl_mask);
152 else if (cpu_is_omap34xx())
153 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
154 clkdm->clktrctrl_mask);
155}
156
157static void _disable_hwsup(struct clockdomain *clkdm)
158{
159 if (cpu_is_omap24xx())
160 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
161 clkdm->clktrctrl_mask);
162 else if (cpu_is_omap34xx())
163 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
164 clkdm->clktrctrl_mask);
165}
166
167static int omap3_clkdm_sleep(struct clockdomain *clkdm)
168{
169 omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
170 clkdm->clktrctrl_mask);
171 return 0;
172}
173
174static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
175{
176 omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
177 clkdm->clktrctrl_mask);
178 return 0;
179}
180
181static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
182{
183 bool hwsup = false;
184
185 if (!clkdm->clktrctrl_mask)
186 return 0;
187
188 hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
189 clkdm->clktrctrl_mask);
190
191 if (hwsup) {
192 /* Disable HW transitions when we are changing deps */
193 _disable_hwsup(clkdm);
194 _clkdm_add_autodeps(clkdm);
195 _enable_hwsup(clkdm);
196 } else {
197 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
198 omap2_clkdm_wakeup(clkdm);
199 }
200
201 return 0;
202}
203
204static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
205{
206 bool hwsup = false;
207
208 if (!clkdm->clktrctrl_mask)
209 return 0;
210
211 hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
212 clkdm->clktrctrl_mask);
213
214 if (hwsup) {
215 /* Disable HW transitions when we are changing deps */
216 _disable_hwsup(clkdm);
217 _clkdm_del_autodeps(clkdm);
218 _enable_hwsup(clkdm);
219 } else {
220 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
221 omap2_clkdm_sleep(clkdm);
222 }
223
224 return 0;
225}
226
227static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
228{
229 if (atomic_read(&clkdm->usecount) > 0)
230 _clkdm_add_autodeps(clkdm);
231
232 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
233 clkdm->clktrctrl_mask);
234}
235
236static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
237{
238 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
239 clkdm->clktrctrl_mask);
240
241 if (atomic_read(&clkdm->usecount) > 0)
242 _clkdm_del_autodeps(clkdm);
243}
244
245static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
246{
247 bool hwsup = false;
248
249 if (!clkdm->clktrctrl_mask)
250 return 0;
251
252 /*
253 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
254 * more details on the unpleasant problem this is working
255 * around
256 */
257 if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
258 (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
259 omap3_clkdm_wakeup(clkdm);
260 return 0;
261 }
262
263 hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
264 clkdm->clktrctrl_mask);
265
266 if (hwsup) {
267 /* Disable HW transitions when we are changing deps */
268 _disable_hwsup(clkdm);
269 _clkdm_add_autodeps(clkdm);
270 _enable_hwsup(clkdm);
271 } else {
272 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
273 omap3_clkdm_wakeup(clkdm);
274 }
275
276 return 0;
277}
278
279static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
280{
281 bool hwsup = false;
282
283 if (!clkdm->clktrctrl_mask)
284 return 0;
285
286 /*
287 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
288 * more details on the unpleasant problem this is working
289 * around
290 */
291 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
292 !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
293 _enable_hwsup(clkdm);
294 return 0;
295 }
296
297 hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
298 clkdm->clktrctrl_mask);
299
300 if (hwsup) {
301 /* Disable HW transitions when we are changing deps */
302 _disable_hwsup(clkdm);
303 _clkdm_del_autodeps(clkdm);
304 _enable_hwsup(clkdm);
305 } else {
306 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
307 omap3_clkdm_sleep(clkdm);
308 }
309
310 return 0;
311}
312
313struct clkdm_ops omap2_clkdm_operations = {
314 .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
315 .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
316 .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
317 .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
318 .clkdm_sleep = omap2_clkdm_sleep,
319 .clkdm_wakeup = omap2_clkdm_wakeup,
320 .clkdm_allow_idle = omap2_clkdm_allow_idle,
321 .clkdm_deny_idle = omap2_clkdm_deny_idle,
322 .clkdm_clk_enable = omap2_clkdm_clk_enable,
323 .clkdm_clk_disable = omap2_clkdm_clk_disable,
324};
325
326struct clkdm_ops omap3_clkdm_operations = {
327 .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
328 .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
329 .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
330 .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
331 .clkdm_add_sleepdep = omap3_clkdm_add_sleepdep,
332 .clkdm_del_sleepdep = omap3_clkdm_del_sleepdep,
333 .clkdm_read_sleepdep = omap3_clkdm_read_sleepdep,
334 .clkdm_clear_all_sleepdeps = omap3_clkdm_clear_all_sleepdeps,
335 .clkdm_sleep = omap3_clkdm_sleep,
336 .clkdm_wakeup = omap3_clkdm_wakeup,
337 .clkdm_allow_idle = omap3_clkdm_allow_idle,
338 .clkdm_deny_idle = omap3_clkdm_deny_idle,
339 .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
340 .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
341};
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 @@
1/*
2 * AM33XX clockdomain control
3 *
4 * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
5 * Vaibhav Hiremath <hvaibhav@ti.com>
6 *
7 * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation version 2.
12 *
13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
14 * kind, whether express or implied; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20
21#include "clockdomain.h"
22#include "cm33xx.h"
23
24
25static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
26{
27 am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
28 return 0;
29}
30
31static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
32{
33 am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
34 return 0;
35}
36
37static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
38{
39 am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
40}
41
42static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
43{
44 am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
45}
46
47static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
48{
49 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
50 return am33xx_clkdm_wakeup(clkdm);
51
52 return 0;
53}
54
55static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
56{
57 bool hwsup = false;
58
59 hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
60
61 if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
62 am33xx_clkdm_sleep(clkdm);
63
64 return 0;
65}
66
67struct clkdm_ops am33xx_clkdm_operations = {
68 .clkdm_sleep = am33xx_clkdm_sleep,
69 .clkdm_wakeup = am33xx_clkdm_wakeup,
70 .clkdm_allow_idle = am33xx_clkdm_allow_idle,
71 .clkdm_deny_idle = am33xx_clkdm_deny_idle,
72 .clkdm_clk_enable = am33xx_clkdm_clk_enable,
73 .clkdm_clk_disable = am33xx_clkdm_clk_disable,
74};
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 @@
1/*
2 * OMAP4 clockdomain control
3 *
4 * Copyright (C) 2008-2010 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation
6 *
7 * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include "clockdomain.h"
17#include "cminst44xx.h"
18#include "cm44xx.h"
19
20static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
21 struct clockdomain *clkdm2)
22{
23 omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
24 clkdm1->prcm_partition,
25 clkdm1->cm_inst, clkdm1->clkdm_offs +
26 OMAP4_CM_STATICDEP);
27 return 0;
28}
29
30static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
31 struct clockdomain *clkdm2)
32{
33 omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
34 clkdm1->prcm_partition,
35 clkdm1->cm_inst, clkdm1->clkdm_offs +
36 OMAP4_CM_STATICDEP);
37 return 0;
38}
39
40static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
41 struct clockdomain *clkdm2)
42{
43 return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
44 clkdm1->cm_inst, clkdm1->clkdm_offs +
45 OMAP4_CM_STATICDEP,
46 (1 << clkdm2->dep_bit));
47}
48
49static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
50{
51 struct clkdm_dep *cd;
52 u32 mask = 0;
53
54 if (!clkdm->prcm_partition)
55 return 0;
56
57 for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
58 if (!cd->clkdm)
59 continue; /* only happens if data is erroneous */
60
61 mask |= 1 << cd->clkdm->dep_bit;
62 atomic_set(&cd->wkdep_usecount, 0);
63 }
64
65 omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
66 clkdm->cm_inst, clkdm->clkdm_offs +
67 OMAP4_CM_STATICDEP);
68 return 0;
69}
70
71static int omap4_clkdm_sleep(struct clockdomain *clkdm)
72{
73 omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
74 clkdm->cm_inst, clkdm->clkdm_offs);
75 return 0;
76}
77
78static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
79{
80 omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
81 clkdm->cm_inst, clkdm->clkdm_offs);
82 return 0;
83}
84
85static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
86{
87 omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
88 clkdm->cm_inst, clkdm->clkdm_offs);
89}
90
91static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
92{
93 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
94 omap4_clkdm_wakeup(clkdm);
95 else
96 omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
97 clkdm->cm_inst,
98 clkdm->clkdm_offs);
99}
100
101static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
102{
103 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
104 return omap4_clkdm_wakeup(clkdm);
105
106 return 0;
107}
108
109static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
110{
111 bool hwsup = false;
112
113 if (!clkdm->prcm_partition)
114 return 0;
115
116 /*
117 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
118 * more details on the unpleasant problem this is working
119 * around
120 */
121 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
122 !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
123 omap4_clkdm_allow_idle(clkdm);
124 return 0;
125 }
126
127 hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
128 clkdm->cm_inst, clkdm->clkdm_offs);
129
130 if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
131 omap4_clkdm_sleep(clkdm);
132
133 return 0;
134}
135
136struct clkdm_ops omap4_clkdm_operations = {
137 .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
138 .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
139 .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
140 .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
141 .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
142 .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
143 .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
144 .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
145 .clkdm_sleep = omap4_clkdm_sleep,
146 .clkdm_wakeup = omap4_clkdm_wakeup,
147 .clkdm_allow_idle = omap4_clkdm_allow_idle,
148 .clkdm_deny_idle = omap4_clkdm_deny_idle,
149 .clkdm_clk_enable = omap4_clkdm_clk_enable,
150 .clkdm_clk_disable = omap4_clkdm_clk_disable,
151};
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index f24e3f7a2bbc..b3cee913dd67 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -33,4 +33,16 @@
33 */ 33 */
34#define MAX_MODULE_DISABLE_TIME 5000 34#define MAX_MODULE_DISABLE_TIME 5000
35 35
36# ifndef __ASSEMBLER__
37
38/**
39 * struct cm_ll_data - fn ptrs to per-SoC CM function implementations
40 */
41struct cm_ll_data {};
42
43extern int cm_register(struct cm_ll_data *cld);
44extern int cm_unregister(struct cm_ll_data *cld);
45
46# endif
47
36#endif 48#endif
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
new file mode 100644
index 000000000000..64165013daf9
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -0,0 +1,255 @@
1/*
2 * OMAP2xxx CM module functions
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
6 * Paul Walmsley
7 * Rajendra Nayak <rnayak@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/delay.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/io.h>
20
21#include "soc.h"
22#include "iomap.h"
23#include "common.h"
24#include "prm2xxx.h"
25#include "cm.h"
26#include "cm2xxx.h"
27#include "cm-regbits-24xx.h"
28#include "clockdomain.h"
29
30/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
31#define DPLL_AUTOIDLE_DISABLE 0x0
32#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
33
34/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
35#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
36#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
37
38static const u8 omap2xxx_cm_idlest_offs[] = {
39 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
40};
41
42/*
43 *
44 */
45
46static void _write_clktrctrl(u8 c, s16 module, u32 mask)
47{
48 u32 v;
49
50 v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
51 v &= ~mask;
52 v |= c << __ffs(mask);
53 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
54}
55
56bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
57{
58 u32 v;
59
60 v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
61 v &= mask;
62 v >>= __ffs(mask);
63
64 return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
65}
66
67void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
68{
69 _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
70}
71
72void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
73{
74 _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
75}
76
77/*
78 * DPLL autoidle control
79 */
80
81static void _omap2xxx_set_dpll_autoidle(u8 m)
82{
83 u32 v;
84
85 v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
86 v &= ~OMAP24XX_AUTO_DPLL_MASK;
87 v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
88 omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
89}
90
91void omap2xxx_cm_set_dpll_disable_autoidle(void)
92{
93 _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
94}
95
96void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
97{
98 _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
99}
100
101/*
102 * APLL autoidle control
103 */
104
105static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
106{
107 u32 v;
108
109 v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
110 v &= ~mask;
111 v |= m << __ffs(mask);
112 omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
113}
114
115void omap2xxx_cm_set_apll54_disable_autoidle(void)
116{
117 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
118 OMAP24XX_AUTO_54M_MASK);
119}
120
121void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
122{
123 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
124 OMAP24XX_AUTO_54M_MASK);
125}
126
127void omap2xxx_cm_set_apll96_disable_autoidle(void)
128{
129 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
130 OMAP24XX_AUTO_96M_MASK);
131}
132
133void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
134{
135 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
136 OMAP24XX_AUTO_96M_MASK);
137}
138
139/*
140 *
141 */
142
143/**
144 * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby
145 * @prcm_mod: PRCM module offset
146 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
147 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
148 *
149 * Wait for the PRCM to indicate that the module identified by
150 * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
151 * success or -EBUSY if the module doesn't enable in time.
152 */
153int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
154{
155 int ena = 0, i = 0;
156 u8 cm_idlest_reg;
157 u32 mask;
158
159 if (!idlest_id || (idlest_id > ARRAY_SIZE(omap2xxx_cm_idlest_offs)))
160 return -EINVAL;
161
162 cm_idlest_reg = omap2xxx_cm_idlest_offs[idlest_id - 1];
163
164 mask = 1 << idlest_shift;
165 ena = mask;
166
167 omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
168 mask) == ena), MAX_MODULE_READY_TIME, i);
169
170 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
171}
172
173/* Clockdomain low-level functions */
174
175static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
176{
177 if (atomic_read(&clkdm->usecount) > 0)
178 _clkdm_add_autodeps(clkdm);
179
180 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
181 clkdm->clktrctrl_mask);
182}
183
184static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
185{
186 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
187 clkdm->clktrctrl_mask);
188
189 if (atomic_read(&clkdm->usecount) > 0)
190 _clkdm_del_autodeps(clkdm);
191}
192
193static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
194{
195 bool hwsup = false;
196
197 if (!clkdm->clktrctrl_mask)
198 return 0;
199
200 hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
201 clkdm->clktrctrl_mask);
202
203 if (hwsup) {
204 /* Disable HW transitions when we are changing deps */
205 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
206 clkdm->clktrctrl_mask);
207 _clkdm_add_autodeps(clkdm);
208 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
209 clkdm->clktrctrl_mask);
210 } else {
211 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
212 omap2xxx_clkdm_wakeup(clkdm);
213 }
214
215 return 0;
216}
217
218static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
219{
220 bool hwsup = false;
221
222 if (!clkdm->clktrctrl_mask)
223 return 0;
224
225 hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
226 clkdm->clktrctrl_mask);
227
228 if (hwsup) {
229 /* Disable HW transitions when we are changing deps */
230 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
231 clkdm->clktrctrl_mask);
232 _clkdm_del_autodeps(clkdm);
233 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
234 clkdm->clktrctrl_mask);
235 } else {
236 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
237 omap2xxx_clkdm_sleep(clkdm);
238 }
239
240 return 0;
241}
242
243struct clkdm_ops omap2_clkdm_operations = {
244 .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
245 .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
246 .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
247 .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
248 .clkdm_sleep = omap2xxx_clkdm_sleep,
249 .clkdm_wakeup = omap2xxx_clkdm_wakeup,
250 .clkdm_allow_idle = omap2xxx_clkdm_allow_idle,
251 .clkdm_deny_idle = omap2xxx_clkdm_deny_idle,
252 .clkdm_clk_enable = omap2xxx_clkdm_clk_enable,
253 .clkdm_clk_disable = omap2xxx_clkdm_clk_disable,
254};
255
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
new file mode 100644
index 000000000000..bce3c4be6d1f
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -0,0 +1,66 @@
1/*
2 * OMAP2xxx Clock Management (CM) register definitions
3 *
4 * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
5 * Copyright (C) 2007-2010 Nokia Corporation
6 * Paul Walmsley
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The CM hardware modules on the OMAP2/3 are quite similar to each
13 * other. The CM modules/instances on OMAP4 are quite different, so
14 * they are handled in a separate file.
15 */
16#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_H
17#define __ARCH_ASM_MACH_OMAP2_CM2XXX_H
18
19#include "prcm-common.h"
20#include "cm2xxx_3xxx.h"
21
22#define OMAP2420_CM_REGADDR(module, reg) \
23 OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
24#define OMAP2430_CM_REGADDR(module, reg) \
25 OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
26
27/*
28 * Module specific CM register offsets from CM_BASE + domain offset
29 * Use cm_{read,write}_mod_reg() with these registers.
30 * These register offsets generally appear in more than one PRCM submodule.
31 */
32
33/* OMAP2-specific register offsets */
34
35#define OMAP24XX_CM_FCLKEN2 0x0004
36#define OMAP24XX_CM_ICLKEN4 0x001c
37#define OMAP24XX_CM_AUTOIDLE4 0x003c
38#define OMAP24XX_CM_IDLEST4 0x002c
39
40/* CM_IDLEST bit field values to indicate deasserted IdleReq */
41
42#define OMAP24XX_CM_IDLEST_VAL 0
43
44
45/* Clock management domain register get/set */
46
47#ifndef __ASSEMBLER__
48
49extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
50extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
51
52extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
53extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
54
55extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
56extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
57extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
58extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
59
60extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
61extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
62 u8 idlest_shift);
63
64#endif
65
66#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 57b2f3c2fbf3..0e26bb1bf7e2 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -18,27 +18,6 @@
18 18
19#include "prcm-common.h" 19#include "prcm-common.h"
20 20
21#define OMAP2420_CM_REGADDR(module, reg) \
22 OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
23#define OMAP2430_CM_REGADDR(module, reg) \
24 OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
25#define OMAP34XX_CM_REGADDR(module, reg) \
26 OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
27
28
29/*
30 * OMAP3-specific global CM registers
31 * Use cm_{read,write}_reg() with these registers.
32 * These registers appear once per CM module.
33 */
34
35#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
36#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
37#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
38
39#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
40#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
41
42/* 21/*
43 * Module specific CM register offsets from CM_BASE + domain offset 22 * Module specific CM register offsets from CM_BASE + domain offset
44 * Use cm_{read,write}_mod_reg() with these registers. 23 * Use cm_{read,write}_mod_reg() with these registers.
@@ -57,6 +36,7 @@
57#define CM_IDLEST 0x0020 36#define CM_IDLEST 0x0020
58#define CM_IDLEST1 CM_IDLEST 37#define CM_IDLEST1 CM_IDLEST
59#define CM_IDLEST2 0x0024 38#define CM_IDLEST2 0x0024
39#define OMAP2430_CM_IDLEST3 0x0028
60#define CM_AUTOIDLE 0x0030 40#define CM_AUTOIDLE 0x0030
61#define CM_AUTOIDLE1 CM_AUTOIDLE 41#define CM_AUTOIDLE1 CM_AUTOIDLE
62#define CM_AUTOIDLE2 0x0034 42#define CM_AUTOIDLE2 0x0034
@@ -66,70 +46,55 @@
66#define CM_CLKSEL2 0x0044 46#define CM_CLKSEL2 0x0044
67#define OMAP2_CM_CLKSTCTRL 0x0048 47#define OMAP2_CM_CLKSTCTRL 0x0048
68 48
69/* OMAP2-specific register offsets */ 49#ifndef __ASSEMBLER__
70
71#define OMAP24XX_CM_FCLKEN2 0x0004
72#define OMAP24XX_CM_ICLKEN4 0x001c
73#define OMAP24XX_CM_AUTOIDLE4 0x003c
74#define OMAP24XX_CM_IDLEST4 0x002c
75
76#define OMAP2430_CM_IDLEST3 0x0028
77
78/* OMAP3-specific register offsets */
79
80#define OMAP3430_CM_CLKEN_PLL 0x0004
81#define OMAP3430ES2_CM_CLKEN2 0x0004
82#define OMAP3430ES2_CM_FCLKEN3 0x0008
83#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
84#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
85#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
86#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
87#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
88#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
89#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
90#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
91#define OMAP3430_CM_CLKSTST 0x004c
92#define OMAP3430ES2_CM_CLKSEL4 0x004c
93#define OMAP3430ES2_CM_CLKSEL5 0x0050
94#define OMAP3430_CM_CLKSEL2_EMU 0x0050
95#define OMAP3430_CM_CLKSEL3_EMU 0x0054
96
97 50
98/* CM_IDLEST bit field values to indicate deasserted IdleReq */ 51#include <linux/io.h>
99 52
100#define OMAP24XX_CM_IDLEST_VAL 0 53static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
101#define OMAP34XX_CM_IDLEST_VAL 1 54{
55 return __raw_readl(cm_base + module + idx);
56}
102 57
58static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
59{
60 __raw_writel(val, cm_base + module + idx);
61}
103 62
104/* Clock management domain register get/set */ 63/* Read-modify-write a register in a CM module. Caller must lock */
64static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
65 s16 idx)
66{
67 u32 v;
105 68
106#ifndef __ASSEMBLER__ 69 v = omap2_cm_read_mod_reg(module, idx);
70 v &= ~mask;
71 v |= bits;
72 omap2_cm_write_mod_reg(v, module, idx);
107 73
108extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx); 74 return v;
109extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx); 75}
110extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
111 76
112extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, 77/* Read a CM register, AND it, and shift the result down to bit 0 */
113 u8 idlest_shift); 78static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
114extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx); 79{
115extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx); 80 u32 v;
116 81
117extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask); 82 v = omap2_cm_read_mod_reg(domain, idx);
118extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); 83 v &= mask;
119extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); 84 v >>= __ffs(mask);
120 85
121extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); 86 return v;
122extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); 87}
123extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
124extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
125 88
126extern void omap2xxx_cm_set_dpll_disable_autoidle(void); 89static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
127extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); 90{
91 return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
92}
128 93
129extern void omap2xxx_cm_set_apll54_disable_autoidle(void); 94static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
130extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); 95{
131extern void omap2xxx_cm_set_apll96_disable_autoidle(void); 96 return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
132extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); 97}
133 98
134#endif 99#endif
135 100
@@ -147,10 +112,4 @@ extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
147#define OMAP_ST_GFX_MASK (1 << 0) 112#define OMAP_ST_GFX_MASK (1 << 0)
148 113
149 114
150/* Function prototypes */
151# ifndef __ASSEMBLER__
152extern void omap3_cm_save_context(void);
153extern void omap3_cm_restore_context(void);
154# endif
155
156#endif 115#endif
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index b4938abf28cc..b2dfcd777194 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -24,6 +24,7 @@
24 24
25#include "../plat-omap/common.h" 25#include "../plat-omap/common.h"
26 26
27#include "clockdomain.h"
27#include "cm.h" 28#include "cm.h"
28#include "cm33xx.h" 29#include "cm33xx.h"
29#include "cm-regbits-34xx.h" 30#include "cm-regbits-34xx.h"
@@ -311,3 +312,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)
311 v &= ~AM33XX_MODULEMODE_MASK; 312 v &= ~AM33XX_MODULEMODE_MASK;
312 am33xx_cm_write_reg(v, inst, clkctrl_offs); 313 am33xx_cm_write_reg(v, inst, clkctrl_offs);
313} 314}
315
316/*
317 * Clockdomain low-level functions
318 */
319
320static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
321{
322 am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
323 return 0;
324}
325
326static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
327{
328 am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
329 return 0;
330}
331
332static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
333{
334 am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
335}
336
337static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
338{
339 am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
340}
341
342static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
343{
344 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
345 return am33xx_clkdm_wakeup(clkdm);
346
347 return 0;
348}
349
350static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
351{
352 bool hwsup = false;
353
354 hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
355
356 if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
357 am33xx_clkdm_sleep(clkdm);
358
359 return 0;
360}
361
362struct clkdm_ops am33xx_clkdm_operations = {
363 .clkdm_sleep = am33xx_clkdm_sleep,
364 .clkdm_wakeup = am33xx_clkdm_wakeup,
365 .clkdm_allow_idle = am33xx_clkdm_allow_idle,
366 .clkdm_deny_idle = am33xx_clkdm_deny_idle,
367 .clkdm_clk_enable = am33xx_clkdm_clk_enable,
368 .clkdm_clk_disable = am33xx_clkdm_clk_disable,
369};
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 7f07ab02a5b3..8b03ec2f4394 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -1,8 +1,10 @@
1/* 1/*
2 * OMAP2/3 CM module functions 2 * OMAP3xxx CM module functions
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009 Nokia Corporation
5 * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
5 * Paul Walmsley 6 * Paul Walmsley
7 * Rajendra Nayak <rnayak@ti.com>
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -12,8 +14,6 @@
12#include <linux/kernel.h> 14#include <linux/kernel.h>
13#include <linux/types.h> 15#include <linux/types.h>
14#include <linux/delay.h> 16#include <linux/delay.h>
15#include <linux/spinlock.h>
16#include <linux/list.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/io.h> 19#include <linux/io.h>
@@ -21,56 +21,16 @@
21#include "soc.h" 21#include "soc.h"
22#include "iomap.h" 22#include "iomap.h"
23#include "common.h" 23#include "common.h"
24#include "prm2xxx_3xxx.h"
24#include "cm.h" 25#include "cm.h"
25#include "cm2xxx_3xxx.h" 26#include "cm3xxx.h"
26#include "cm-regbits-24xx.h"
27#include "cm-regbits-34xx.h" 27#include "cm-regbits-34xx.h"
28#include "clockdomain.h"
28 29
29/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */ 30static const u8 omap3xxx_cm_idlest_offs[] = {
30#define DPLL_AUTOIDLE_DISABLE 0x0 31 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
31#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
32
33/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
34#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
35#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
36
37static const u8 cm_idlest_offs[] = {
38 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
39}; 32};
40 33
41u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
42{
43 return __raw_readl(cm_base + module + idx);
44}
45
46void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
47{
48 __raw_writel(val, cm_base + module + idx);
49}
50
51/* Read-modify-write a register in a CM module. Caller must lock */
52u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
53{
54 u32 v;
55
56 v = omap2_cm_read_mod_reg(module, idx);
57 v &= ~mask;
58 v |= bits;
59 omap2_cm_write_mod_reg(v, module, idx);
60
61 return v;
62}
63
64u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
65{
66 return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
67}
68
69u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
70{
71 return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
72}
73
74/* 34/*
75 * 35 *
76 */ 36 */
@@ -85,33 +45,15 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask)
85 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); 45 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
86} 46}
87 47
88bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask) 48bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
89{ 49{
90 u32 v; 50 u32 v;
91 bool ret = 0;
92
93 BUG_ON(!cpu_is_omap24xx() && !cpu_is_omap34xx());
94 51
95 v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL); 52 v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
96 v &= mask; 53 v &= mask;
97 v >>= __ffs(mask); 54 v >>= __ffs(mask);
98 55
99 if (cpu_is_omap24xx()) 56 return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
100 ret = (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
101 else
102 ret = (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
103
104 return ret;
105}
106
107void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
108{
109 _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
110}
111
112void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
113{
114 _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
115} 57}
116 58
117void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) 59void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
@@ -135,109 +77,209 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
135} 77}
136 78
137/* 79/*
138 * DPLL autoidle control 80 *
139 */ 81 */
140 82
141static void _omap2xxx_set_dpll_autoidle(u8 m) 83/**
84 * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
85 * @prcm_mod: PRCM module offset
86 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
87 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
88 *
89 * Wait for the PRCM to indicate that the module identified by
90 * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
91 * success or -EBUSY if the module doesn't enable in time.
92 */
93int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
142{ 94{
143 u32 v; 95 int ena = 0, i = 0;
96 u8 cm_idlest_reg;
97 u32 mask;
98
99 if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
100 return -EINVAL;
101
102 cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
103
104 mask = 1 << idlest_shift;
105 ena = 0;
106
107 omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
108 mask) == ena), MAX_MODULE_READY_TIME, i);
144 109
145 v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); 110 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
146 v &= ~OMAP24XX_AUTO_DPLL_MASK;
147 v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
148 omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
149} 111}
150 112
151void omap2xxx_cm_set_dpll_disable_autoidle(void) 113/* Clockdomain low-level operations */
114
115static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
116 struct clockdomain *clkdm2)
152{ 117{
153 _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP); 118 omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
119 clkdm1->pwrdm.ptr->prcm_offs,
120 OMAP3430_CM_SLEEPDEP);
121 return 0;
154} 122}
155 123
156void omap2xxx_cm_set_dpll_auto_low_power_stop(void) 124static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
125 struct clockdomain *clkdm2)
157{ 126{
158 _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE); 127 omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
128 clkdm1->pwrdm.ptr->prcm_offs,
129 OMAP3430_CM_SLEEPDEP);
130 return 0;
159} 131}
160 132
161/* 133static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
162 * APLL autoidle control 134 struct clockdomain *clkdm2)
163 */
164
165static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
166{ 135{
167 u32 v; 136 return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
168 137 OMAP3430_CM_SLEEPDEP,
169 v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); 138 (1 << clkdm2->dep_bit));
170 v &= ~mask;
171 v |= m << __ffs(mask);
172 omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
173} 139}
174 140
175void omap2xxx_cm_set_apll54_disable_autoidle(void) 141static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
176{ 142{
177 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP, 143 struct clkdm_dep *cd;
178 OMAP24XX_AUTO_54M_MASK); 144 u32 mask = 0;
145
146 for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
147 if (!cd->clkdm)
148 continue; /* only happens if data is erroneous */
149
150 mask |= 1 << cd->clkdm->dep_bit;
151 atomic_set(&cd->sleepdep_usecount, 0);
152 }
153 omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
154 OMAP3430_CM_SLEEPDEP);
155 return 0;
179} 156}
180 157
181void omap2xxx_cm_set_apll54_auto_low_power_stop(void) 158static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
182{ 159{
183 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE, 160 omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
184 OMAP24XX_AUTO_54M_MASK); 161 clkdm->clktrctrl_mask);
162 return 0;
185} 163}
186 164
187void omap2xxx_cm_set_apll96_disable_autoidle(void) 165static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
188{ 166{
189 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP, 167 omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
190 OMAP24XX_AUTO_96M_MASK); 168 clkdm->clktrctrl_mask);
169 return 0;
191} 170}
192 171
193void omap2xxx_cm_set_apll96_auto_low_power_stop(void) 172static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
194{ 173{
195 _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE, 174 if (atomic_read(&clkdm->usecount) > 0)
196 OMAP24XX_AUTO_96M_MASK); 175 _clkdm_add_autodeps(clkdm);
197}
198 176
199/* 177 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
200 * 178 clkdm->clktrctrl_mask);
201 */ 179}
202 180
203/** 181static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
204 * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
205 * @prcm_mod: PRCM module offset
206 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
207 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
208 *
209 * XXX document
210 */
211int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
212{ 182{
213 int ena = 0, i = 0; 183 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
214 u8 cm_idlest_reg; 184 clkdm->clktrctrl_mask);
215 u32 mask;
216 185
217 if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs))) 186 if (atomic_read(&clkdm->usecount) > 0)
218 return -EINVAL; 187 _clkdm_del_autodeps(clkdm);
188}
219 189
220 cm_idlest_reg = cm_idlest_offs[idlest_id - 1]; 190static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
191{
192 bool hwsup = false;
221 193
222 mask = 1 << idlest_shift; 194 if (!clkdm->clktrctrl_mask)
195 return 0;
223 196
224 if (cpu_is_omap24xx()) 197 /*
225 ena = mask; 198 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
226 else if (cpu_is_omap34xx()) 199 * more details on the unpleasant problem this is working
227 ena = 0; 200 * around
228 else 201 */
229 BUG(); 202 if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
203 (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
204 omap3xxx_clkdm_wakeup(clkdm);
205 return 0;
206 }
207
208 hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
209 clkdm->clktrctrl_mask);
210
211 if (hwsup) {
212 /* Disable HW transitions when we are changing deps */
213 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
214 clkdm->clktrctrl_mask);
215 _clkdm_add_autodeps(clkdm);
216 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
217 clkdm->clktrctrl_mask);
218 } else {
219 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
220 omap3xxx_clkdm_wakeup(clkdm);
221 }
222
223 return 0;
224}
230 225
231 omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena), 226static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
232 MAX_MODULE_READY_TIME, i); 227{
228 bool hwsup = false;
233 229
234 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; 230 if (!clkdm->clktrctrl_mask)
231 return 0;
232
233 /*
234 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
235 * more details on the unpleasant problem this is working
236 * around
237 */
238 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
239 !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
240 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
241 clkdm->clktrctrl_mask);
242 return 0;
243 }
244
245 hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
246 clkdm->clktrctrl_mask);
247
248 if (hwsup) {
249 /* Disable HW transitions when we are changing deps */
250 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
251 clkdm->clktrctrl_mask);
252 _clkdm_del_autodeps(clkdm);
253 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
254 clkdm->clktrctrl_mask);
255 } else {
256 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
257 omap3xxx_clkdm_sleep(clkdm);
258 }
259
260 return 0;
235} 261}
236 262
263struct clkdm_ops omap3_clkdm_operations = {
264 .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
265 .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
266 .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
267 .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
268 .clkdm_add_sleepdep = omap3xxx_clkdm_add_sleepdep,
269 .clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep,
270 .clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep,
271 .clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps,
272 .clkdm_sleep = omap3xxx_clkdm_sleep,
273 .clkdm_wakeup = omap3xxx_clkdm_wakeup,
274 .clkdm_allow_idle = omap3xxx_clkdm_allow_idle,
275 .clkdm_deny_idle = omap3xxx_clkdm_deny_idle,
276 .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
277 .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
278};
279
237/* 280/*
238 * Context save/restore code - OMAP3 only 281 * Context save/restore code - OMAP3 only
239 */ 282 */
240#ifdef CONFIG_ARCH_OMAP3
241struct omap3_cm_regs { 283struct omap3_cm_regs {
242 u32 iva2_cm_clksel1; 284 u32 iva2_cm_clksel1;
243 u32 iva2_cm_clksel2; 285 u32 iva2_cm_clksel2;
@@ -555,4 +597,3 @@ void omap3_cm_restore_context(void)
555 omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD, 597 omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
556 OMAP3_CM_CLKOUT_CTRL_OFFSET); 598 OMAP3_CM_CLKOUT_CTRL_OFFSET);
557} 599}
558#endif
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h
new file mode 100644
index 000000000000..4a6ac812edf4
--- /dev/null
+++ b/arch/arm/mach-omap2/cm3xxx.h
@@ -0,0 +1,86 @@
1/*
2 * OMAP2/3 Clock Management (CM) register definitions
3 *
4 * Copyright (C) 2007-2009 Texas Instruments, Inc.
5 * Copyright (C) 2007-2010 Nokia Corporation
6 * Paul Walmsley
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The CM hardware modules on the OMAP2/3 are quite similar to each
13 * other. The CM modules/instances on OMAP4 are quite different, so
14 * they are handled in a separate file.
15 */
16#ifndef __ARCH_ASM_MACH_OMAP2_CM3XXX_H
17#define __ARCH_ASM_MACH_OMAP2_CM3XXX_H
18
19#include "prcm-common.h"
20#include "cm2xxx_3xxx.h"
21
22#define OMAP34XX_CM_REGADDR(module, reg) \
23 OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
24
25
26/*
27 * OMAP3-specific global CM registers
28 * Use cm_{read,write}_reg() with these registers.
29 * These registers appear once per CM module.
30 */
31
32#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
33#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
34#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
35
36#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
37#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
38
39/*
40 * Module specific CM register offsets from CM_BASE + domain offset
41 * Use cm_{read,write}_mod_reg() with these registers.
42 * These register offsets generally appear in more than one PRCM submodule.
43 */
44
45/* OMAP3-specific register offsets */
46
47#define OMAP3430_CM_CLKEN_PLL 0x0004
48#define OMAP3430ES2_CM_CLKEN2 0x0004
49#define OMAP3430ES2_CM_FCLKEN3 0x0008
50#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
51#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
52#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
53#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
54#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
55#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
56#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
57#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
58#define OMAP3430_CM_CLKSTST 0x004c
59#define OMAP3430ES2_CM_CLKSEL4 0x004c
60#define OMAP3430ES2_CM_CLKSEL5 0x0050
61#define OMAP3430_CM_CLKSEL2_EMU 0x0050
62#define OMAP3430_CM_CLKSEL3_EMU 0x0054
63
64
65/* CM_IDLEST bit field values to indicate deasserted IdleReq */
66
67#define OMAP34XX_CM_IDLEST_VAL 1
68
69
70#ifndef __ASSEMBLER__
71
72extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
73extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
74extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
75extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
76
77extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
78extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
79 u8 idlest_shift);
80
81extern void omap3_cm_save_context(void);
82extern void omap3_cm_restore_context(void);
83
84#endif
85
86#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..3246cef151dc
--- /dev/null
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -0,0 +1,71 @@
1/*
2 * OMAP2+ common Clock Management (CM) IP block functions
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 * Paul Walmsley <paul@pwsan.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * XXX This code should eventually be moved to a CM driver.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16
17#include "cm2xxx.h"
18#include "cm3xxx.h"
19#include "cm44xx.h"
20
21/*
22 * cm_ll_data: function pointers to SoC-specific implementations of
23 * common CM functions
24 */
25static struct cm_ll_data null_cm_ll_data;
26static struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
27
28/**
29 * cm_register - register per-SoC low-level data with the CM
30 * @cld: low-level per-SoC OMAP CM data & function pointers to register
31 *
32 * Register per-SoC low-level OMAP CM data and function pointers with
33 * the OMAP CM common interface. The caller must keep the data
34 * pointed to by @cld valid until it calls cm_unregister() and
35 * it returns successfully. Returns 0 upon success, -EINVAL if @cld
36 * is NULL, or -EEXIST if cm_register() has already been called
37 * without an intervening cm_unregister().
38 */
39int cm_register(struct cm_ll_data *cld)
40{
41 if (!cld)
42 return -EINVAL;
43
44 if (cm_ll_data != &null_cm_ll_data)
45 return -EEXIST;
46
47 cm_ll_data = cld;
48
49 return 0;
50}
51
52/**
53 * cm_unregister - unregister per-SoC low-level data & function pointers
54 * @cld: low-level per-SoC OMAP CM data & function pointers to unregister
55 *
56 * Unregister per-SoC low-level OMAP CM data and function pointers
57 * that were previously registered with cm_register(). The
58 * caller may not destroy any of the data pointed to by @cld until
59 * this function returns successfully. Returns 0 upon success, or
60 * -EINVAL if @cld is NULL or if @cld does not match the struct
61 * cm_ll_data * previously registered by cm_register().
62 */
63int cm_unregister(struct cm_ll_data *cld)
64{
65 if (!cld || cm_ll_data != cld)
66 return -EINVAL;
67
68 cm_ll_data = &null_cm_ll_data;
69
70 return 0;
71}
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 @@
2 * OMAP4 CM instance functions 2 * OMAP4 CM instance functions
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009 Nokia Corporation
5 * Copyright (C) 2011 Texas Instruments, Inc. 5 * Copyright (C) 2008-2011 Texas Instruments, Inc.
6 * Paul Walmsley 6 * Paul Walmsley
7 * Rajendra Nayak <rnayak@ti.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -22,6 +23,7 @@
22 23
23#include "iomap.h" 24#include "iomap.h"
24#include "common.h" 25#include "common.h"
26#include "clockdomain.h"
25#include "cm.h" 27#include "cm.h"
26#include "cm1_44xx.h" 28#include "cm1_44xx.h"
27#include "cm2_44xx.h" 29#include "cm2_44xx.h"
@@ -343,3 +345,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
343 v &= ~OMAP4430_MODULEMODE_MASK; 345 v &= ~OMAP4430_MODULEMODE_MASK;
344 omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); 346 omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
345} 347}
348
349/*
350 * Clockdomain low-level functions
351 */
352
353static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
354 struct clockdomain *clkdm2)
355{
356 omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
357 clkdm1->prcm_partition,
358 clkdm1->cm_inst, clkdm1->clkdm_offs +
359 OMAP4_CM_STATICDEP);
360 return 0;
361}
362
363static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
364 struct clockdomain *clkdm2)
365{
366 omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
367 clkdm1->prcm_partition,
368 clkdm1->cm_inst, clkdm1->clkdm_offs +
369 OMAP4_CM_STATICDEP);
370 return 0;
371}
372
373static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
374 struct clockdomain *clkdm2)
375{
376 return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
377 clkdm1->cm_inst,
378 clkdm1->clkdm_offs +
379 OMAP4_CM_STATICDEP,
380 (1 << clkdm2->dep_bit));
381}
382
383static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
384{
385 struct clkdm_dep *cd;
386 u32 mask = 0;
387
388 if (!clkdm->prcm_partition)
389 return 0;
390
391 for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
392 if (!cd->clkdm)
393 continue; /* only happens if data is erroneous */
394
395 mask |= 1 << cd->clkdm->dep_bit;
396 atomic_set(&cd->wkdep_usecount, 0);
397 }
398
399 omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
400 clkdm->cm_inst, clkdm->clkdm_offs +
401 OMAP4_CM_STATICDEP);
402 return 0;
403}
404
405static int omap4_clkdm_sleep(struct clockdomain *clkdm)
406{
407 omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
408 clkdm->cm_inst, clkdm->clkdm_offs);
409 return 0;
410}
411
412static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
413{
414 omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
415 clkdm->cm_inst, clkdm->clkdm_offs);
416 return 0;
417}
418
419static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
420{
421 omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
422 clkdm->cm_inst, clkdm->clkdm_offs);
423}
424
425static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
426{
427 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
428 omap4_clkdm_wakeup(clkdm);
429 else
430 omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
431 clkdm->cm_inst,
432 clkdm->clkdm_offs);
433}
434
435static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
436{
437 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
438 return omap4_clkdm_wakeup(clkdm);
439
440 return 0;
441}
442
443static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
444{
445 bool hwsup = false;
446
447 if (!clkdm->prcm_partition)
448 return 0;
449
450 /*
451 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
452 * more details on the unpleasant problem this is working
453 * around
454 */
455 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
456 !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
457 omap4_clkdm_allow_idle(clkdm);
458 return 0;
459 }
460
461 hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
462 clkdm->cm_inst, clkdm->clkdm_offs);
463
464 if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
465 omap4_clkdm_sleep(clkdm);
466
467 return 0;
468}
469
470struct clkdm_ops omap4_clkdm_operations = {
471 .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
472 .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
473 .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
474 .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
475 .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
476 .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
477 .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
478 .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
479 .clkdm_sleep = omap4_clkdm_sleep,
480 .clkdm_wakeup = omap4_clkdm_wakeup,
481 .clkdm_allow_idle = omap4_clkdm_allow_idle,
482 .clkdm_deny_idle = omap4_clkdm_deny_idle,
483 .clkdm_clk_enable = omap4_clkdm_clk_enable,
484 .clkdm_clk_disable = omap4_clkdm_clk_disable,
485};
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index bf2be5c5468d..06375ad20917 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -20,8 +20,8 @@
20#include "common.h" 20#include "common.h"
21#include "cm-regbits-34xx.h" 21#include "cm-regbits-34xx.h"
22#include "prm-regbits-34xx.h" 22#include "prm-regbits-34xx.h"
23#include "prm2xxx_3xxx.h" 23#include "prm3xxx.h"
24#include "cm2xxx_3xxx.h" 24#include "cm3xxx.h"
25#include "sdrc.h" 25#include "sdrc.h"
26#include "pm.h" 26#include "pm.h"
27#include "control.h" 27#include "control.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 87eee3b62a3c..37eeb45612f8 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -147,10 +147,11 @@
147#include "common.h" 147#include "common.h"
148#include "clockdomain.h" 148#include "clockdomain.h"
149#include "powerdomain.h" 149#include "powerdomain.h"
150#include "cm2xxx_3xxx.h" 150#include "cm2xxx.h"
151#include "cm3xxx.h"
151#include "cminst44xx.h" 152#include "cminst44xx.h"
152#include "cm33xx.h" 153#include "cm33xx.h"
153#include "prm2xxx_3xxx.h" 154#include "prm3xxx.h"
154#include "prm44xx.h" 155#include "prm44xx.h"
155#include "prm33xx.h" 156#include "prm33xx.h"
156#include "prminst44xx.h" 157#include "prminst44xx.h"
@@ -2668,7 +2669,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
2668/* Static functions intended only for use in soc_ops field function pointers */ 2669/* Static functions intended only for use in soc_ops field function pointers */
2669 2670
2670/** 2671/**
2671 * _omap2_wait_target_ready - wait for a module to leave slave idle 2672 * _omap2xxx_wait_target_ready - wait for a module to leave slave idle
2672 * @oh: struct omap_hwmod * 2673 * @oh: struct omap_hwmod *
2673 * 2674 *
2674 * Wait for a module @oh to leave slave idle. Returns 0 if the module 2675 * Wait for a module @oh to leave slave idle. Returns 0 if the module
@@ -2676,7 +2677,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
2676 * slave idle; otherwise, pass along the return value of the 2677 * slave idle; otherwise, pass along the return value of the
2677 * appropriate *_cm*_wait_module_ready() function. 2678 * appropriate *_cm*_wait_module_ready() function.
2678 */ 2679 */
2679static int _omap2_wait_target_ready(struct omap_hwmod *oh) 2680static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh)
2680{ 2681{
2681 if (!oh) 2682 if (!oh)
2682 return -EINVAL; 2683 return -EINVAL;
@@ -2689,9 +2690,36 @@ static int _omap2_wait_target_ready(struct omap_hwmod *oh)
2689 2690
2690 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ 2691 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
2691 2692
2692 return omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, 2693 return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
2693 oh->prcm.omap2.idlest_reg_id, 2694 oh->prcm.omap2.idlest_reg_id,
2694 oh->prcm.omap2.idlest_idle_bit); 2695 oh->prcm.omap2.idlest_idle_bit);
2696}
2697
2698/**
2699 * _omap3xxx_wait_target_ready - wait for a module to leave slave idle
2700 * @oh: struct omap_hwmod *
2701 *
2702 * Wait for a module @oh to leave slave idle. Returns 0 if the module
2703 * does not have an IDLEST bit or if the module successfully leaves
2704 * slave idle; otherwise, pass along the return value of the
2705 * appropriate *_cm*_wait_module_ready() function.
2706 */
2707static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh)
2708{
2709 if (!oh)
2710 return -EINVAL;
2711
2712 if (oh->flags & HWMOD_NO_IDLEST)
2713 return 0;
2714
2715 if (!_find_mpu_rt_port(oh))
2716 return 0;
2717
2718 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
2719
2720 return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
2721 oh->prcm.omap2.idlest_reg_id,
2722 oh->prcm.omap2.idlest_idle_bit);
2695} 2723}
2696 2724
2697/** 2725/**
@@ -3959,8 +3987,13 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
3959 */ 3987 */
3960void __init omap_hwmod_init(void) 3988void __init omap_hwmod_init(void)
3961{ 3989{
3962 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 3990 if (cpu_is_omap24xx()) {
3963 soc_ops.wait_target_ready = _omap2_wait_target_ready; 3991 soc_ops.wait_target_ready = _omap2xxx_wait_target_ready;
3992 soc_ops.assert_hardreset = _omap2_assert_hardreset;
3993 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
3994 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
3995 } else if (cpu_is_omap34xx()) {
3996 soc_ops.wait_target_ready = _omap3xxx_wait_target_ready;
3964 soc_ops.assert_hardreset = _omap2_assert_hardreset; 3997 soc_ops.assert_hardreset = _omap2_assert_hardreset;
3965 soc_ops.deassert_hardreset = _omap2_deassert_hardreset; 3998 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
3966 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; 3999 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 6d17e044ffb8..83815ddc4786 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -43,9 +43,9 @@
43#include "soc.h" 43#include "soc.h"
44#include "common.h" 44#include "common.h"
45#include "clock.h" 45#include "clock.h"
46#include "prm2xxx_3xxx.h" 46#include "prm2xxx.h"
47#include "prm-regbits-24xx.h" 47#include "prm-regbits-24xx.h"
48#include "cm2xxx_3xxx.h" 48#include "cm2xxx.h"
49#include "cm-regbits-24xx.h" 49#include "cm-regbits-24xx.h"
50#include "sdrc.h" 50#include "sdrc.h"
51#include "pm.h" 51#include "pm.h"
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 160fa250c41e..2f1ad87c1bb0 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -44,12 +44,11 @@
44 44
45#include "soc.h" 45#include "soc.h"
46#include "common.h" 46#include "common.h"
47#include "cm2xxx_3xxx.h" 47#include "cm3xxx.h"
48#include "cm-regbits-34xx.h" 48#include "cm-regbits-34xx.h"
49#include "gpmc.h" 49#include "gpmc.h"
50#include "prm-regbits-34xx.h" 50#include "prm-regbits-34xx.h"
51 51#include "prm3xxx.h"
52#include "prm2xxx_3xxx.h"
53#include "pm.h" 52#include "pm.h"
54#include "sdrc.h" 53#include "sdrc.h"
55#include "control.h" 54#include "control.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 @@
1/*
2 * OMAP2 and OMAP3 powerdomain control
3 *
4 * Copyright (C) 2009-2011 Texas Instruments, Inc.
5 * Copyright (C) 2007-2009 Nokia Corporation
6 *
7 * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/io.h>
16#include <linux/errno.h>
17#include <linux/delay.h>
18#include <linux/bug.h>
19
20#include <plat/prcm.h>
21
22#include "powerdomain.h"
23#include "prm.h"
24#include "prm-regbits-24xx.h"
25#include "prm-regbits-34xx.h"
26
27
28/* Common functions across OMAP2 and OMAP3 */
29static int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
30{
31 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
32 (pwrst << OMAP_POWERSTATE_SHIFT),
33 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
34 return 0;
35}
36
37static int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
38{
39 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
40 OMAP2_PM_PWSTCTRL,
41 OMAP_POWERSTATE_MASK);
42}
43
44static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
45{
46 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
47 OMAP2_PM_PWSTST,
48 OMAP_POWERSTATEST_MASK);
49}
50
51static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
52 u8 pwrst)
53{
54 u32 m;
55
56 m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
57
58 omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
59 OMAP2_PM_PWSTCTRL);
60
61 return 0;
62}
63
64static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
65 u8 pwrst)
66{
67 u32 m;
68
69 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
70
71 omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
72 OMAP2_PM_PWSTCTRL);
73
74 return 0;
75}
76
77static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
78{
79 u32 m;
80
81 m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
82
83 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
84 m);
85}
86
87static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
88{
89 u32 m;
90
91 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
92
93 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
94 OMAP2_PM_PWSTCTRL, m);
95}
96
97static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
98{
99 u32 v;
100
101 v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
102 omap2_prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
103 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
104
105 return 0;
106}
107
108static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
109{
110 u32 c = 0;
111
112 /*
113 * REVISIT: pwrdm_wait_transition() may be better implemented
114 * via a callback and a periodic timer check -- how long do we expect
115 * powerdomain transitions to take?
116 */
117
118 /* XXX Is this udelay() value meaningful? */
119 while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
120 OMAP_INTRANSITION_MASK) &&
121 (c++ < PWRDM_TRANSITION_BAILOUT))
122 udelay(1);
123
124 if (c > PWRDM_TRANSITION_BAILOUT) {
125 pr_err("powerdomain: %s: waited too long to complete transition\n",
126 pwrdm->name);
127 return -EAGAIN;
128 }
129
130 pr_debug("powerdomain: completed transition in %d loops\n", c);
131
132 return 0;
133}
134
135/* Applicable only for OMAP3. Not supported on OMAP2 */
136static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
137{
138 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
139 OMAP3430_PM_PREPWSTST,
140 OMAP3430_LASTPOWERSTATEENTERED_MASK);
141}
142
143static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
144{
145 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
146 OMAP2_PM_PWSTST,
147 OMAP3430_LOGICSTATEST_MASK);
148}
149
150static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
151{
152 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
153 OMAP2_PM_PWSTCTRL,
154 OMAP3430_LOGICSTATEST_MASK);
155}
156
157static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
158{
159 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
160 OMAP3430_PM_PREPWSTST,
161 OMAP3430_LASTLOGICSTATEENTERED_MASK);
162}
163
164static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
165{
166 switch (bank) {
167 case 0:
168 return OMAP3430_LASTMEM1STATEENTERED_MASK;
169 case 1:
170 return OMAP3430_LASTMEM2STATEENTERED_MASK;
171 case 2:
172 return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
173 case 3:
174 return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
175 default:
176 WARN_ON(1); /* should never happen */
177 return -EEXIST;
178 }
179 return 0;
180}
181
182static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
183{
184 u32 m;
185
186 m = omap3_get_mem_bank_lastmemst_mask(bank);
187
188 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
189 OMAP3430_PM_PREPWSTST, m);
190}
191
192static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
193{
194 omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
195 return 0;
196}
197
198static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
199{
200 return omap2_prm_rmw_mod_reg_bits(0,
201 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
202 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
203}
204
205static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
206{
207 return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
208 0, pwrdm->prcm_offs,
209 OMAP2_PM_PWSTCTRL);
210}
211
212struct pwrdm_ops omap2_pwrdm_operations = {
213 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
214 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
215 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
216 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
217 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
218 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
219 .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
220 .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
221 .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
222};
223
224struct pwrdm_ops omap3_pwrdm_operations = {
225 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
226 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
227 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
228 .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
229 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
230 .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
231 .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
232 .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
233 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
234 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
235 .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
236 .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
237 .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
238 .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
239 .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
240 .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
241 .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
242};
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 @@
1/*
2 * AM33XX Powerdomain control
3 *
4 * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * Derived from mach-omap2/powerdomain44xx.c written by Rajendra Nayak
7 * <rnayak@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation version 2.
12 *
13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
14 * kind, whether express or implied; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/io.h>
20#include <linux/errno.h>
21#include <linux/delay.h>
22
23#include <plat/prcm.h>
24
25#include "powerdomain.h"
26#include "prm33xx.h"
27#include "prm-regbits-33xx.h"
28
29
30static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
31{
32 am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
33 (pwrst << OMAP_POWERSTATE_SHIFT),
34 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
35 return 0;
36}
37
38static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
39{
40 u32 v;
41
42 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
43 v &= OMAP_POWERSTATE_MASK;
44 v >>= OMAP_POWERSTATE_SHIFT;
45
46 return v;
47}
48
49static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
50{
51 u32 v;
52
53 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
54 v &= OMAP_POWERSTATEST_MASK;
55 v >>= OMAP_POWERSTATEST_SHIFT;
56
57 return v;
58}
59
60static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
61{
62 u32 v;
63
64 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
65 v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
66 v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
67
68 return v;
69}
70
71static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
72{
73 am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
74 (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
75 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
76 return 0;
77}
78
79static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
80{
81 am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
82 AM33XX_LASTPOWERSTATEENTERED_MASK,
83 pwrdm->prcm_offs, pwrdm->pwrstst_offs);
84 return 0;
85}
86
87static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
88{
89 u32 m;
90
91 m = pwrdm->logicretstate_mask;
92 if (!m)
93 return -EINVAL;
94
95 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
96 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
97
98 return 0;
99}
100
101static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
102{
103 u32 v;
104
105 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
106 v &= AM33XX_LOGICSTATEST_MASK;
107 v >>= AM33XX_LOGICSTATEST_SHIFT;
108
109 return v;
110}
111
112static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
113{
114 u32 v, m;
115
116 m = pwrdm->logicretstate_mask;
117 if (!m)
118 return -EINVAL;
119
120 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
121 v &= m;
122 v >>= __ffs(m);
123
124 return v;
125}
126
127static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
128 u8 pwrst)
129{
130 u32 m;
131
132 m = pwrdm->mem_on_mask[bank];
133 if (!m)
134 return -EINVAL;
135
136 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
137 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
138
139 return 0;
140}
141
142static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
143 u8 pwrst)
144{
145 u32 m;
146
147 m = pwrdm->mem_ret_mask[bank];
148 if (!m)
149 return -EINVAL;
150
151 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
152 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
153
154 return 0;
155}
156
157static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
158{
159 u32 m, v;
160
161 m = pwrdm->mem_pwrst_mask[bank];
162 if (!m)
163 return -EINVAL;
164
165 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
166 v &= m;
167 v >>= __ffs(m);
168
169 return v;
170}
171
172static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
173{
174 u32 m, v;
175
176 m = pwrdm->mem_retst_mask[bank];
177 if (!m)
178 return -EINVAL;
179
180 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
181 v &= m;
182 v >>= __ffs(m);
183
184 return v;
185}
186
187static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
188{
189 u32 c = 0;
190
191 /*
192 * REVISIT: pwrdm_wait_transition() may be better implemented
193 * via a callback and a periodic timer check -- how long do we expect
194 * powerdomain transitions to take?
195 */
196
197 /* XXX Is this udelay() value meaningful? */
198 while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
199 & OMAP_INTRANSITION_MASK) &&
200 (c++ < PWRDM_TRANSITION_BAILOUT))
201 udelay(1);
202
203 if (c > PWRDM_TRANSITION_BAILOUT) {
204 pr_err("powerdomain: %s: waited too long to complete transition\n",
205 pwrdm->name);
206 return -EAGAIN;
207 }
208
209 pr_debug("powerdomain: completed transition in %d loops\n", c);
210
211 return 0;
212}
213
214struct pwrdm_ops am33xx_pwrdm_operations = {
215 .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
216 .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
217 .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
218 .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
219 .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
220 .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
221 .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
222 .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
223 .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
224 .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
225 .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
226 .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
227 .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
228 .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
229};
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 @@
1/*
2 * OMAP4 powerdomain control
3 *
4 * Copyright (C) 2009-2010, 2012 Texas Instruments, Inc.
5 * Copyright (C) 2007-2009 Nokia Corporation
6 *
7 * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/io.h>
16#include <linux/errno.h>
17#include <linux/delay.h>
18#include <linux/bug.h>
19
20#include "powerdomain.h"
21#include <plat/prcm.h>
22#include "prm2xxx_3xxx.h"
23#include "prm44xx.h"
24#include "prminst44xx.h"
25#include "prm-regbits-44xx.h"
26
27static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
28{
29 omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
30 (pwrst << OMAP_POWERSTATE_SHIFT),
31 pwrdm->prcm_partition,
32 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
33 return 0;
34}
35
36static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
37{
38 u32 v;
39
40 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
41 OMAP4_PM_PWSTCTRL);
42 v &= OMAP_POWERSTATE_MASK;
43 v >>= OMAP_POWERSTATE_SHIFT;
44
45 return v;
46}
47
48static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
49{
50 u32 v;
51
52 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
53 OMAP4_PM_PWSTST);
54 v &= OMAP_POWERSTATEST_MASK;
55 v >>= OMAP_POWERSTATEST_SHIFT;
56
57 return v;
58}
59
60static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
61{
62 u32 v;
63
64 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
65 OMAP4_PM_PWSTST);
66 v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
67 v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
68
69 return v;
70}
71
72static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
73{
74 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
75 (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
76 pwrdm->prcm_partition,
77 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
78 return 0;
79}
80
81static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
82{
83 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
84 OMAP4430_LASTPOWERSTATEENTERED_MASK,
85 pwrdm->prcm_partition,
86 pwrdm->prcm_offs, OMAP4_PM_PWSTST);
87 return 0;
88}
89
90static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
91{
92 u32 v;
93
94 v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
95 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
96 pwrdm->prcm_partition, pwrdm->prcm_offs,
97 OMAP4_PM_PWSTCTRL);
98
99 return 0;
100}
101
102static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
103 u8 pwrst)
104{
105 u32 m;
106
107 m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
108
109 omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
110 pwrdm->prcm_partition, pwrdm->prcm_offs,
111 OMAP4_PM_PWSTCTRL);
112
113 return 0;
114}
115
116static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
117 u8 pwrst)
118{
119 u32 m;
120
121 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
122
123 omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
124 pwrdm->prcm_partition, pwrdm->prcm_offs,
125 OMAP4_PM_PWSTCTRL);
126
127 return 0;
128}
129
130static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
131{
132 u32 v;
133
134 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
135 OMAP4_PM_PWSTST);
136 v &= OMAP4430_LOGICSTATEST_MASK;
137 v >>= OMAP4430_LOGICSTATEST_SHIFT;
138
139 return v;
140}
141
142static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
143{
144 u32 v;
145
146 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
147 OMAP4_PM_PWSTCTRL);
148 v &= OMAP4430_LOGICRETSTATE_MASK;
149 v >>= OMAP4430_LOGICRETSTATE_SHIFT;
150
151 return v;
152}
153
154/**
155 * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
156 * @pwrdm: struct powerdomain * to read the state for
157 *
158 * Reads the previous logic powerstate for a powerdomain. This
159 * function must determine the previous logic powerstate by first
160 * checking the previous powerstate for the domain. If that was OFF,
161 * then logic has been lost. If previous state was RETENTION, the
162 * function reads the setting for the next retention logic state to
163 * see the actual value. In every other case, the logic is
164 * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
165 * depending whether the logic was retained or not.
166 */
167static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
168{
169 int state;
170
171 state = omap4_pwrdm_read_prev_pwrst(pwrdm);
172
173 if (state == PWRDM_POWER_OFF)
174 return PWRDM_POWER_OFF;
175
176 if (state != PWRDM_POWER_RET)
177 return PWRDM_POWER_RET;
178
179 return omap4_pwrdm_read_logic_retst(pwrdm);
180}
181
182static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
183{
184 u32 m, v;
185
186 m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
187
188 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
189 OMAP4_PM_PWSTST);
190 v &= m;
191 v >>= __ffs(m);
192
193 return v;
194}
195
196static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
197{
198 u32 m, v;
199
200 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
201
202 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
203 OMAP4_PM_PWSTCTRL);
204 v &= m;
205 v >>= __ffs(m);
206
207 return v;
208}
209
210/**
211 * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
212 * @pwrdm: struct powerdomain * to read mem powerstate for
213 * @bank: memory bank index
214 *
215 * Reads the previous memory powerstate for a powerdomain. This
216 * function must determine the previous memory powerstate by first
217 * checking the previous powerstate for the domain. If that was OFF,
218 * then logic has been lost. If previous state was RETENTION, the
219 * function reads the setting for the next memory retention state to
220 * see the actual value. In every other case, the logic is
221 * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
222 * depending whether logic was retained or not.
223 */
224static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
225{
226 int state;
227
228 state = omap4_pwrdm_read_prev_pwrst(pwrdm);
229
230 if (state == PWRDM_POWER_OFF)
231 return PWRDM_POWER_OFF;
232
233 if (state != PWRDM_POWER_RET)
234 return PWRDM_POWER_RET;
235
236 return omap4_pwrdm_read_mem_retst(pwrdm, bank);
237}
238
239static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
240{
241 u32 c = 0;
242
243 /*
244 * REVISIT: pwrdm_wait_transition() may be better implemented
245 * via a callback and a periodic timer check -- how long do we expect
246 * powerdomain transitions to take?
247 */
248
249 /* XXX Is this udelay() value meaningful? */
250 while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
251 pwrdm->prcm_offs,
252 OMAP4_PM_PWSTST) &
253 OMAP_INTRANSITION_MASK) &&
254 (c++ < PWRDM_TRANSITION_BAILOUT))
255 udelay(1);
256
257 if (c > PWRDM_TRANSITION_BAILOUT) {
258 pr_err("powerdomain: %s: waited too long to complete transition\n",
259 pwrdm->name);
260 return -EAGAIN;
261 }
262
263 pr_debug("powerdomain: completed transition in %d loops\n", c);
264
265 return 0;
266}
267
268struct pwrdm_ops omap4_pwrdm_operations = {
269 .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
270 .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
271 .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
272 .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
273 .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
274 .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
275 .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
276 .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
277 .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst,
278 .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
279 .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
280 .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
281 .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
282 .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
283 .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
284 .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
285};
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 @@
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 */ 15 */
16 16
17#include "prm2xxx_3xxx.h" 17#include "prm2xxx.h"
18 18
19/* Bits shared between registers */ 19/* Bits shared between registers */
20 20
@@ -209,9 +209,13 @@
209 209
210/* RM_RSTST_WKUP specific bits */ 210/* RM_RSTST_WKUP specific bits */
211/* 2430 calls EXTWMPU_RST "EXTWARM_RST" and GLOBALWMPU_RST "GLOBALWARM_RST" */ 211/* 2430 calls EXTWMPU_RST "EXTWARM_RST" and GLOBALWMPU_RST "GLOBALWARM_RST" */
212#define OMAP24XX_EXTWMPU_RST_SHIFT 6
212#define OMAP24XX_EXTWMPU_RST_MASK (1 << 6) 213#define OMAP24XX_EXTWMPU_RST_MASK (1 << 6)
214#define OMAP24XX_SECU_WD_RST_SHIFT 5
213#define OMAP24XX_SECU_WD_RST_MASK (1 << 5) 215#define OMAP24XX_SECU_WD_RST_MASK (1 << 5)
216#define OMAP24XX_MPU_WD_RST_SHIFT 4
214#define OMAP24XX_MPU_WD_RST_MASK (1 << 4) 217#define OMAP24XX_MPU_WD_RST_MASK (1 << 4)
218#define OMAP24XX_SECU_VIOL_RST_SHIFT 3
215#define OMAP24XX_SECU_VIOL_RST_MASK (1 << 3) 219#define OMAP24XX_SECU_VIOL_RST_MASK (1 << 3)
216 220
217/* PM_WKEN_WKUP specific bits */ 221/* 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 @@
14#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H 14#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
15 15
16 16
17#include "prm2xxx_3xxx.h" 17#include "prm3xxx.h"
18 18
19/* Shared register bits */ 19/* Shared register bits */
20 20
@@ -509,15 +509,25 @@
509#define OMAP3430_RSTTIME1_MASK (0xff << 0) 509#define OMAP3430_RSTTIME1_MASK (0xff << 0)
510 510
511/* PRM_RSTST */ 511/* PRM_RSTST */
512#define OMAP3430_ICECRUSHER_RST_SHIFT 10
512#define OMAP3430_ICECRUSHER_RST_MASK (1 << 10) 513#define OMAP3430_ICECRUSHER_RST_MASK (1 << 10)
514#define OMAP3430_ICEPICK_RST_SHIFT 9
513#define OMAP3430_ICEPICK_RST_MASK (1 << 9) 515#define OMAP3430_ICEPICK_RST_MASK (1 << 9)
516#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT 8
514#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_MASK (1 << 8) 517#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_MASK (1 << 8)
518#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT 7
515#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_MASK (1 << 7) 519#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_MASK (1 << 7)
520#define OMAP3430_EXTERNAL_WARM_RST_SHIFT 6
516#define OMAP3430_EXTERNAL_WARM_RST_MASK (1 << 6) 521#define OMAP3430_EXTERNAL_WARM_RST_MASK (1 << 6)
522#define OMAP3430_SECURE_WD_RST_SHIFT 5
517#define OMAP3430_SECURE_WD_RST_MASK (1 << 5) 523#define OMAP3430_SECURE_WD_RST_MASK (1 << 5)
524#define OMAP3430_MPU_WD_RST_SHIFT 4
518#define OMAP3430_MPU_WD_RST_MASK (1 << 4) 525#define OMAP3430_MPU_WD_RST_MASK (1 << 4)
526#define OMAP3430_SECURITY_VIOL_RST_SHIFT 3
519#define OMAP3430_SECURITY_VIOL_RST_MASK (1 << 3) 527#define OMAP3430_SECURITY_VIOL_RST_MASK (1 << 3)
528#define OMAP3430_GLOBAL_SW_RST_SHIFT 1
520#define OMAP3430_GLOBAL_SW_RST_MASK (1 << 1) 529#define OMAP3430_GLOBAL_SW_RST_MASK (1 << 1)
530#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0
521#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) 531#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0)
522 532
523/* PRM_VOLTCTRL */ 533/* PRM_VOLTCTRL */
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 39d562169d18..c30ab5de8d1d 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -52,5 +52,58 @@
52#define OMAP_POWERSTATE_SHIFT 0 52#define OMAP_POWERSTATE_SHIFT 0
53#define OMAP_POWERSTATE_MASK (0x3 << 0) 53#define OMAP_POWERSTATE_MASK (0x3 << 0)
54 54
55/*
56 * Standardized OMAP reset source bits
57 *
58 * To the extent these happen to match the hardware register bit
59 * shifts, it's purely coincidental. Used by omap-wdt.c.
60 * OMAP_UNKNOWN_RST_SRC_ID_SHIFT is a special value, used whenever
61 * there are any bits remaining in the global PRM_RSTST register that
62 * haven't been identified, or when the PRM code for the current SoC
63 * doesn't know how to interpret the register.
64 */
65#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
66#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
67#define OMAP_SECU_VIOL_RST_SRC_ID_SHIFT 2
68#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
69#define OMAP_SECU_WD_RST_SRC_ID_SHIFT 4
70#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
71#define OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT 6
72#define OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT 7
73#define OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT 8
74#define OMAP_ICEPICK_RST_SRC_ID_SHIFT 9
75#define OMAP_ICECRUSHER_RST_SRC_ID_SHIFT 10
76#define OMAP_C2C_RST_SRC_ID_SHIFT 11
77#define OMAP_UNKNOWN_RST_SRC_ID_SHIFT 12
78
79#ifndef __ASSEMBLER__
80
81/**
82 * struct prm_reset_src_map - map register bitshifts to standard bitshifts
83 * @reg_shift: bitshift in the PRM reset source register
84 * @std_shift: bitshift equivalent in the standard reset source list
85 *
86 * The fields are signed because -1 is used as a terminator.
87 */
88struct prm_reset_src_map {
89 s8 reg_shift;
90 s8 std_shift;
91};
92
93/**
94 * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
95 * @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl
96 */
97struct prm_ll_data {
98 u32 (*read_reset_sources)(void);
99};
100
101extern int prm_register(struct prm_ll_data *pld);
102extern int prm_unregister(struct prm_ll_data *pld);
103
104extern u32 prm_read_reset_sources(void);
105
106#endif
107
55 108
56#endif 109#endif
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
new file mode 100644
index 000000000000..e2860f9c111d
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -0,0 +1,126 @@
1/*
2 * OMAP2xxx PRM module functions
3 *
4 * Copyright (C) 2010-2012 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson
7 * Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/irq.h>
20
21#include "common.h"
22#include <plat/cpu.h>
23#include <plat/prcm.h>
24
25#include "vp.h"
26#include "powerdomain.h"
27#include "clockdomain.h"
28#include "prm2xxx.h"
29#include "cm2xxx_3xxx.h"
30#include "prm-regbits-24xx.h"
31
32/*
33 * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP
34 * hardware register (which are specific to the OMAP2xxx SoCs) to
35 * reset source ID bit shifts (which is an OMAP SoC-independent
36 * enumeration)
37 */
38static struct prm_reset_src_map omap2xxx_prm_reset_src_map[] = {
39 { OMAP_GLOBALCOLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
40 { OMAP_GLOBALWARM_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
41 { OMAP24XX_SECU_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
42 { OMAP24XX_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
43 { OMAP24XX_SECU_WD_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
44 { OMAP24XX_EXTWMPU_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
45 { -1, -1 },
46};
47
48/**
49 * omap2xxx_prm_read_reset_sources - return the last SoC reset source
50 *
51 * Return a u32 representing the last reset sources of the SoC. The
52 * returned reset source bits are standardized across OMAP SoCs.
53 */
54static u32 omap2xxx_prm_read_reset_sources(void)
55{
56 struct prm_reset_src_map *p;
57 u32 r = 0;
58 u32 v;
59
60 v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
61
62 p = omap2xxx_prm_reset_src_map;
63 while (p->reg_shift >= 0 && p->std_shift >= 0) {
64 if (v & (1 << p->reg_shift))
65 r |= 1 << p->std_shift;
66 p++;
67 }
68
69 return r;
70}
71
72int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
73{
74 omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
75 clkdm->pwrdm.ptr->prcm_offs,
76 OMAP2_PM_PWSTCTRL);
77 return 0;
78}
79
80int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
81{
82 omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
83 clkdm->pwrdm.ptr->prcm_offs,
84 OMAP2_PM_PWSTCTRL);
85 return 0;
86}
87
88struct pwrdm_ops omap2_pwrdm_operations = {
89 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
90 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
91 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
92 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
93 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
94 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
95 .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
96 .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
97 .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
98};
99
100/*
101 *
102 */
103
104static struct prm_ll_data omap2xxx_prm_ll_data = {
105 .read_reset_sources = &omap2xxx_prm_read_reset_sources,
106};
107
108static int __init omap2xxx_prm_init(void)
109{
110 if (!cpu_is_omap24xx())
111 return 0;
112
113 return prm_register(&omap2xxx_prm_ll_data);
114}
115subsys_initcall(omap2xxx_prm_init);
116
117static void __exit omap2xxx_prm_exit(void)
118{
119 if (!cpu_is_omap24xx())
120 return;
121
122 /* Should never happen */
123 WARN(prm_unregister(&omap2xxx_prm_ll_data),
124 "%s: prm_ll_data function pointer mismatch\n", __func__);
125}
126__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..1d97112524f1
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -0,0 +1,132 @@
1/*
2 * OMAP2xxx Power/Reset Management (PRM) register definitions
3 *
4 * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Paul Walmsley
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The PRM hardware modules on the OMAP2/3 are quite similar to each
13 * other. The PRM on OMAP4 has a new register layout, and is handled
14 * in a separate file.
15 */
16#ifndef __ARCH_ARM_MACH_OMAP2_PRM2XXX_H
17#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_H
18
19#include "prcm-common.h"
20#include "prm.h"
21#include "prm2xxx_3xxx.h"
22
23#define OMAP2420_PRM_REGADDR(module, reg) \
24 OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
25#define OMAP2430_PRM_REGADDR(module, reg) \
26 OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
27
28/*
29 * OMAP2-specific global PRM registers
30 * Use __raw_{read,write}l() with these registers.
31 *
32 * With a few exceptions, these are the register names beginning with
33 * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE
34 * bits.)
35 *
36 */
37
38#define OMAP2_PRCM_REVISION_OFFSET 0x0000
39#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
40#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
41#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
42
43#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
44#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
45#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
46#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
47
48#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
49#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
50#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
51#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
52#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
53#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
54#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
55#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
56#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
57#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
58#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
59#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
60#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
61#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
62#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
63#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
64#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
65#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
66#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
67#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
68
69#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
70#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
71
72#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
73#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
74
75#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
76#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
77#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
78#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
79#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
80#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
81#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
82#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
83#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
84#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
85
86/*
87 * Module specific PRM register offsets from PRM_BASE + domain offset
88 *
89 * Use prm_{read,write}_mod_reg() with these registers.
90 *
91 * With a few exceptions, these are the register names beginning with
92 * {PM,RM}_* on both OMAP2/3 SoC families.. (The exceptions are the
93 * IRQSTATUS and IRQENABLE bits.)
94 */
95
96/* Register offsets appearing on both OMAP2 and OMAP3 */
97
98#define OMAP2_RM_RSTCTRL 0x0050
99#define OMAP2_RM_RSTTIME 0x0054
100#define OMAP2_RM_RSTST 0x0058
101#define OMAP2_PM_PWSTCTRL 0x00e0
102#define OMAP2_PM_PWSTST 0x00e4
103
104#define PM_WKEN 0x00a0
105#define PM_WKEN1 PM_WKEN
106#define PM_WKST 0x00b0
107#define PM_WKST1 PM_WKST
108#define PM_WKDEP 0x00c8
109#define PM_EVGENCTRL 0x00d4
110#define PM_EVGENONTIM 0x00d8
111#define PM_EVGENOFFTIM 0x00dc
112
113/* OMAP2xxx specific register offsets */
114#define OMAP24XX_PM_WKEN2 0x00a4
115#define OMAP24XX_PM_WKST2 0x00b4
116
117#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
118#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
119#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
120#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
121
122#ifndef __ASSEMBLER__
123/* Function prototypes */
124extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
125extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
126
127extern int __init prm2xxx_init(void);
128extern int __exit prm2xxx_exit(void);
129
130#endif
131
132#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 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/irq.h>
19 18
20#include <plat/prcm.h>
21
22#include "soc.h"
23#include "common.h" 19#include "common.h"
24#include "vp.h" 20#include "powerdomain.h"
25
26#include "prm2xxx_3xxx.h" 21#include "prm2xxx_3xxx.h"
27#include "cm2xxx_3xxx.h"
28#include "prm-regbits-24xx.h" 22#include "prm-regbits-24xx.h"
29#include "prm-regbits-34xx.h" 23#include "clockdomain.h"
30
31static const struct omap_prcm_irq omap3_prcm_irqs[] = {
32 OMAP_PRCM_IRQ("wkup", 0, 0),
33 OMAP_PRCM_IRQ("io", 9, 1),
34};
35
36static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
37 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
38 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
39 .nr_regs = 1,
40 .irqs = omap3_prcm_irqs,
41 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
42 .irq = 11 + OMAP_INTC_START,
43 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
44 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
45 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
46 .restore_irqen = &omap3xxx_prm_restore_irqen,
47};
48
49u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
50{
51 return __raw_readl(prm_base + module + idx);
52}
53
54void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
55{
56 __raw_writel(val, prm_base + module + idx);
57}
58
59/* Read-modify-write a register in a PRM module. Caller must lock */
60u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
61{
62 u32 v;
63
64 v = omap2_prm_read_mod_reg(module, idx);
65 v &= ~mask;
66 v |= bits;
67 omap2_prm_write_mod_reg(v, module, idx);
68
69 return v;
70}
71
72/* Read a PRM register, AND it, and shift the result down to bit 0 */
73u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
74{
75 u32 v;
76
77 v = omap2_prm_read_mod_reg(domain, idx);
78 v &= mask;
79 v >>= __ffs(mask);
80
81 return v;
82}
83
84u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
85{
86 return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
87}
88
89u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
90{
91 return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
92}
93
94 24
95/** 25/**
96 * omap2_prm_is_hardreset_asserted - read the HW reset line state of 26 * 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)
104 */ 34 */
105int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) 35int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
106{ 36{
107 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
108 return -EINVAL;
109
110 return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, 37 return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
111 (1 << shift)); 38 (1 << shift));
112} 39}
@@ -127,9 +54,6 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
127{ 54{
128 u32 mask; 55 u32 mask;
129 56
130 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
131 return -EINVAL;
132
133 mask = 1 << shift; 57 mask = 1 << shift;
134 omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL); 58 omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
135 59
@@ -156,9 +80,6 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
156 u32 rst, st; 80 u32 rst, st;
157 int c; 81 int c;
158 82
159 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
160 return -EINVAL;
161
162 rst = 1 << rst_shift; 83 rst = 1 << rst_shift;
163 st = 1 << st_shift; 84 st = 1 << st_shift;
164 85
@@ -178,188 +99,155 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
178 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; 99 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
179} 100}
180 101
181/* PRM VP */
182
183/*
184 * struct omap3_vp - OMAP3 VP register access description.
185 * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
186 */
187struct omap3_vp {
188 u32 tranxdone_status;
189};
190
191static struct omap3_vp omap3_vp[] = {
192 [OMAP3_VP_VDD_MPU_ID] = {
193 .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
194 },
195 [OMAP3_VP_VDD_CORE_ID] = {
196 .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
197 },
198};
199
200#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
201
202u32 omap3_prm_vp_check_txdone(u8 vp_id)
203{
204 struct omap3_vp *vp = &omap3_vp[vp_id];
205 u32 irqstatus;
206 102
207 irqstatus = omap2_prm_read_mod_reg(OCP_MOD, 103/* Powerdomain low-level functions */
208 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
209 return irqstatus & vp->tranxdone_status;
210}
211 104
212void omap3_prm_vp_clear_txdone(u8 vp_id) 105/* Common functions across OMAP2 and OMAP3 */
106int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
213{ 107{
214 struct omap3_vp *vp = &omap3_vp[vp_id]; 108 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
215 109 (pwrst << OMAP_POWERSTATE_SHIFT),
216 omap2_prm_write_mod_reg(vp->tranxdone_status, 110 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
217 OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 111 return 0;
218} 112}
219 113
220u32 omap3_prm_vcvp_read(u8 offset) 114int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
221{ 115{
222 return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset); 116 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
117 OMAP2_PM_PWSTCTRL,
118 OMAP_POWERSTATE_MASK);
223} 119}
224 120
225void omap3_prm_vcvp_write(u32 val, u8 offset) 121int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
226{ 122{
227 omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset); 123 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
124 OMAP2_PM_PWSTST,
125 OMAP_POWERSTATEST_MASK);
228} 126}
229 127
230u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) 128int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
129 u8 pwrst)
231{ 130{
232 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); 131 u32 m;
132
133 m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
134
135 omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
136 OMAP2_PM_PWSTCTRL);
137
138 return 0;
233} 139}
234 140
235/** 141int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
236 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events 142 u8 pwrst)
237 * @events: ptr to a u32, preallocated by caller
238 *
239 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
240 * MPU IRQs, and store the result into the u32 pointed to by @events.
241 * No return value.
242 */
243void omap3xxx_prm_read_pending_irqs(unsigned long *events)
244{ 143{
245 u32 mask, st; 144 u32 m;
145
146 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
246 147
247 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */ 148 omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
248 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); 149 OMAP2_PM_PWSTCTRL);
249 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
250 150
251 events[0] = mask & st; 151 return 0;
252} 152}
253 153
254/** 154int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
255 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
256 *
257 * Force any buffered writes to the PRM IP block to complete. Needed
258 * by the PRM IRQ handler, which reads and writes directly to the IP
259 * block, to avoid race conditions after acknowledging or clearing IRQ
260 * bits. No return value.
261 */
262void omap3xxx_prm_ocp_barrier(void)
263{ 155{
264 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); 156 u32 m;
157
158 m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
159
160 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
161 m);
265} 162}
266 163
267/** 164int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
268 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
269 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
270 *
271 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
272 * must be allocated by the caller. Intended to be used in the PRM
273 * interrupt handler suspend callback. The OCP barrier is needed to
274 * ensure the write to disable PRM interrupts reaches the PRM before
275 * returning; otherwise, spurious interrupts might occur. No return
276 * value.
277 */
278void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
279{ 165{
280 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, 166 u32 m;
281 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 167
282 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); 168 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
283 169
284 /* OCP barrier */ 170 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
285 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); 171 OMAP2_PM_PWSTCTRL, m);
286} 172}
287 173
288/** 174int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
289 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
290 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
291 *
292 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
293 * to be used in the PRM interrupt handler resume callback to restore
294 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
295 * barrier should be needed here; any pending PRM interrupts will fire
296 * once the writes reach the PRM. No return value.
297 */
298void omap3xxx_prm_restore_irqen(u32 *saved_mask)
299{ 175{
300 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, 176 u32 v;
301 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 177
178 v = pwrst << __ffs(OMAP_LOGICRETSTATE_MASK);
179 omap2_prm_rmw_mod_reg_bits(OMAP_LOGICRETSTATE_MASK, v, pwrdm->prcm_offs,
180 OMAP2_PM_PWSTCTRL);
181
182 return 0;
302} 183}
303 184
304/** 185int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
305 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
306 *
307 * Clear any previously-latched I/O wakeup events and ensure that the
308 * I/O wakeup gates are aligned with the current mux settings. Works
309 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
310 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
311 * return value.
312 */
313void omap3xxx_prm_reconfigure_io_chain(void)
314{ 186{
315 int i = 0; 187 u32 c = 0;
316 188
317 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, 189 /*
318 PM_WKEN); 190 * REVISIT: pwrdm_wait_transition() may be better implemented
191 * via a callback and a periodic timer check -- how long do we expect
192 * powerdomain transitions to take?
193 */
319 194
320 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & 195 /* XXX Is this udelay() value meaningful? */
321 OMAP3430_ST_IO_CHAIN_MASK, 196 while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
322 MAX_IOPAD_LATCH_TIME, i); 197 OMAP_INTRANSITION_MASK) &&
323 if (i == MAX_IOPAD_LATCH_TIME) 198 (c++ < PWRDM_TRANSITION_BAILOUT))
324 pr_warn("PRM: I/O chain clock line assertion timed out\n"); 199 udelay(1);
325 200
326 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, 201 if (c > PWRDM_TRANSITION_BAILOUT) {
327 PM_WKEN); 202 pr_err("powerdomain: %s: waited too long to complete transition\n",
203 pwrdm->name);
204 return -EAGAIN;
205 }
328 206
329 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD, 207 pr_debug("powerdomain: completed transition in %d loops\n", c);
330 PM_WKST);
331 208
332 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST); 209 return 0;
333} 210}
334 211
335/** 212int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
336 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches 213 struct clockdomain *clkdm2)
337 * 214{
338 * Activates the I/O wakeup event latches and allows events logged by 215 omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
339 * those latches to signal a wakeup event to the PRCM. For I/O 216 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
340 * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux 217 return 0;
341 * registers, and omap3xxx_prm_reconfigure_io_chain() must be called. 218}
342 * No return value. 219
343 */ 220int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
344static void __init omap3xxx_prm_enable_io_wakeup(void) 221 struct clockdomain *clkdm2)
222{
223 omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
224 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
225 return 0;
226}
227
228int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
229 struct clockdomain *clkdm2)
345{ 230{
346 if (omap3_has_io_wakeup()) 231 return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
347 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, 232 PM_WKDEP, (1 << clkdm2->dep_bit));
348 PM_WKEN);
349} 233}
350 234
351static int __init omap3xxx_prcm_init(void) 235int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
352{ 236{
353 int ret = 0; 237 struct clkdm_dep *cd;
354 238 u32 mask = 0;
355 if (cpu_is_omap34xx()) { 239
356 omap3xxx_prm_enable_io_wakeup(); 240 for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
357 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); 241 if (!cd->clkdm)
358 if (!ret) 242 continue; /* only happens if data is erroneous */
359 irq_set_status_flags(omap_prcm_event_to_irq("io"), 243
360 IRQ_NOAUTOEN); 244 /* PRM accesses are slow, so minimize them */
245 mask |= 1 << cd->clkdm->dep_bit;
246 atomic_set(&cd->wkdep_usecount, 0);
361 } 247 }
362 248
363 return ret; 249 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
250 PM_WKDEP);
251 return 0;
364} 252}
365subsys_initcall(omap3xxx_prcm_init); 253
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index c19d249b4816..3330b1bf789d 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2/3 Power/Reset Management (PRM) register definitions 2 * OMAP2xxx/3xxx-common Power/Reset Management (PRM) register definitions
3 * 3 *
4 * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc. 4 * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation 5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Paul Walmsley 6 * Paul Walmsley
7 * 7 *
@@ -19,160 +19,6 @@
19#include "prcm-common.h" 19#include "prcm-common.h"
20#include "prm.h" 20#include "prm.h"
21 21
22#define OMAP2420_PRM_REGADDR(module, reg) \
23 OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
24#define OMAP2430_PRM_REGADDR(module, reg) \
25 OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
26#define OMAP34XX_PRM_REGADDR(module, reg) \
27 OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
28
29
30/*
31 * OMAP2-specific global PRM registers
32 * Use __raw_{read,write}l() with these registers.
33 *
34 * With a few exceptions, these are the register names beginning with
35 * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE
36 * bits.)
37 *
38 */
39
40#define OMAP2_PRCM_REVISION_OFFSET 0x0000
41#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
42#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
43#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
44
45#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
46#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
47#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
48#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
49
50#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
51#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
52#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
53#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
54#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
55#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
56#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
57#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
58#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
59#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
60#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
61#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
62#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
63#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
64#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
65#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
66#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
67#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
68#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
69#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
70
71#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
72#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
73
74#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
75#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
76
77#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
78#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
79#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
80#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
81#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
82#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
83#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
84#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
85#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
86#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
87
88/*
89 * OMAP3-specific global PRM registers
90 * Use __raw_{read,write}l() with these registers.
91 *
92 * With a few exceptions, these are the register names beginning with
93 * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE
94 * bits.)
95 */
96
97#define OMAP3_PRM_REVISION_OFFSET 0x0004
98#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
99#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
100#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
101
102#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
103#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
104#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
105#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
106
107
108#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
109#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
110#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
111#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
112#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
113#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
114#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
115#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
116#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
117#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
118#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
119#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
120#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
121#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
122#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
123#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
124#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
125#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
126#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
127#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
128#define OMAP3_PRM_RSTST_OFFSET 0x0058
129#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
130#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
131#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
132#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
133#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
134#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
135#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
136#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
137#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
138#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
139#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
140#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
141#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
142#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
143#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
144#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
145#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
146#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
147#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
148#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
149#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
150#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
151#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
152#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
153#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
154#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
155#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
156#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
157#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
158#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
159#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
160#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
161#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
162#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
163#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
164#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
165#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
166#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
167#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
168#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
169#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
170
171#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
172#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
173#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
174#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
175
176/* 22/*
177 * Module specific PRM register offsets from PRM_BASE + domain offset 23 * Module specific PRM register offsets from PRM_BASE + domain offset
178 * 24 *
@@ -200,66 +46,83 @@
200#define PM_EVGENONTIM 0x00d8 46#define PM_EVGENONTIM 0x00d8
201#define PM_EVGENOFFTIM 0x00dc 47#define PM_EVGENOFFTIM 0x00dc
202 48
203/* OMAP2xxx specific register offsets */
204#define OMAP24XX_PM_WKEN2 0x00a4
205#define OMAP24XX_PM_WKST2 0x00b4
206
207#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
208#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
209#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
210#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
211
212/* OMAP3 specific register offsets */
213#define OMAP3430ES2_PM_WKEN3 0x00f0
214#define OMAP3430ES2_PM_WKST3 0x00b8
215
216#define OMAP3430_PM_MPUGRPSEL 0x00a4
217#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
218#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
219 49
220#define OMAP3430_PM_IVAGRPSEL 0x00a8 50#ifndef __ASSEMBLER__
221#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
222#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
223
224#define OMAP3430_PM_PREPWSTST 0x00e8
225
226#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
227#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
228 51
52#include <linux/io.h>
53#include "powerdomain.h"
229 54
230#ifndef __ASSEMBLER__
231/* Power/reset management domain register get/set */ 55/* Power/reset management domain register get/set */
232extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx); 56static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
233extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx); 57{
234extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); 58 return __raw_readl(prm_base + module + idx);
235extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx); 59}
236extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx); 60
237extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask); 61static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
62{
63 __raw_writel(val, prm_base + module + idx);
64}
65
66/* Read-modify-write a register in a PRM module. Caller must lock */
67static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
68 s16 idx)
69{
70 u32 v;
71
72 v = omap2_prm_read_mod_reg(module, idx);
73 v &= ~mask;
74 v |= bits;
75 omap2_prm_write_mod_reg(v, module, idx);
76
77 return v;
78}
79
80/* Read a PRM register, AND it, and shift the result down to bit 0 */
81static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
82{
83 u32 v;
84
85 v = omap2_prm_read_mod_reg(domain, idx);
86 v &= mask;
87 v >>= __ffs(mask);
88
89 return v;
90}
91
92static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
93{
94 return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
95}
96
97static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
98{
99 return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
100}
238 101
239/* These omap2_ PRM functions apply to both OMAP2 and 3 */ 102/* These omap2_ PRM functions apply to both OMAP2 and 3 */
240extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); 103extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
241extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); 104extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
242extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); 105extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
243 106
244/* OMAP3-specific VP functions */ 107extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
245u32 omap3_prm_vp_check_txdone(u8 vp_id); 108extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
246void omap3_prm_vp_clear_txdone(u8 vp_id); 109extern int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm);
247 110extern int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
248/* 111 u8 pwrst);
249 * OMAP3 access functions for voltage controller (VC) and 112extern int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
250 * voltage proccessor (VP) in the PRM. 113 u8 pwrst);
251 */ 114extern int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
252extern u32 omap3_prm_vcvp_read(u8 offset); 115extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
253extern void omap3_prm_vcvp_write(u32 val, u8 offset); 116extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
254extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 117extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm);
255 118
256extern void omap3xxx_prm_reconfigure_io_chain(void); 119extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
257 120 struct clockdomain *clkdm2);
258/* PRM interrupt-related functions */ 121extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
259extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); 122 struct clockdomain *clkdm2);
260extern void omap3xxx_prm_ocp_barrier(void); 123extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
261extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); 124 struct clockdomain *clkdm2);
262extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); 125extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
263 126
264#endif /* __ASSEMBLER */ 127#endif /* __ASSEMBLER */
265 128
@@ -348,7 +211,9 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
348 * 211 *
349 * 3430: RM_RSTST_CORE, RM_RSTST_EMU 212 * 3430: RM_RSTST_CORE, RM_RSTST_EMU
350 */ 213 */
214#define OMAP_GLOBALWARM_RST_SHIFT 1
351#define OMAP_GLOBALWARM_RST_MASK (1 << 1) 215#define OMAP_GLOBALWARM_RST_MASK (1 << 1)
216#define OMAP_GLOBALCOLD_RST_SHIFT 0
352#define OMAP_GLOBALCOLD_RST_MASK (1 << 0) 217#define OMAP_GLOBALCOLD_RST_MASK (1 << 0)
353 218
354/* 219/*
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 624ade5c3c33..53ec9cbaa3d3 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -22,6 +22,7 @@
22#include "../plat-omap/common.h" 22#include "../plat-omap/common.h"
23 23
24#include "common.h" 24#include "common.h"
25#include "powerdomain.h"
25#include "prm33xx.h" 26#include "prm33xx.h"
26#include "prm-regbits-33xx.h" 27#include "prm-regbits-33xx.h"
27 28
@@ -133,3 +134,204 @@ int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
133 134
134 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; 135 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
135} 136}
137
138static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
139{
140 am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
141 (pwrst << OMAP_POWERSTATE_SHIFT),
142 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
143 return 0;
144}
145
146static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
147{
148 u32 v;
149
150 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
151 v &= OMAP_POWERSTATE_MASK;
152 v >>= OMAP_POWERSTATE_SHIFT;
153
154 return v;
155}
156
157static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
158{
159 u32 v;
160
161 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
162 v &= OMAP_POWERSTATEST_MASK;
163 v >>= OMAP_POWERSTATEST_SHIFT;
164
165 return v;
166}
167
168static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
169{
170 u32 v;
171
172 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
173 v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
174 v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
175
176 return v;
177}
178
179static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
180{
181 am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
182 (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
183 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
184 return 0;
185}
186
187static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
188{
189 am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
190 AM33XX_LASTPOWERSTATEENTERED_MASK,
191 pwrdm->prcm_offs, pwrdm->pwrstst_offs);
192 return 0;
193}
194
195static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
196{
197 u32 m;
198
199 m = pwrdm->logicretstate_mask;
200 if (!m)
201 return -EINVAL;
202
203 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
204 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
205
206 return 0;
207}
208
209static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
210{
211 u32 v;
212
213 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
214 v &= AM33XX_LOGICSTATEST_MASK;
215 v >>= AM33XX_LOGICSTATEST_SHIFT;
216
217 return v;
218}
219
220static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
221{
222 u32 v, m;
223
224 m = pwrdm->logicretstate_mask;
225 if (!m)
226 return -EINVAL;
227
228 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
229 v &= m;
230 v >>= __ffs(m);
231
232 return v;
233}
234
235static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
236 u8 pwrst)
237{
238 u32 m;
239
240 m = pwrdm->mem_on_mask[bank];
241 if (!m)
242 return -EINVAL;
243
244 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
245 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
246
247 return 0;
248}
249
250static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
251 u8 pwrst)
252{
253 u32 m;
254
255 m = pwrdm->mem_ret_mask[bank];
256 if (!m)
257 return -EINVAL;
258
259 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
260 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
261
262 return 0;
263}
264
265static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
266{
267 u32 m, v;
268
269 m = pwrdm->mem_pwrst_mask[bank];
270 if (!m)
271 return -EINVAL;
272
273 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
274 v &= m;
275 v >>= __ffs(m);
276
277 return v;
278}
279
280static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
281{
282 u32 m, v;
283
284 m = pwrdm->mem_retst_mask[bank];
285 if (!m)
286 return -EINVAL;
287
288 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
289 v &= m;
290 v >>= __ffs(m);
291
292 return v;
293}
294
295static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
296{
297 u32 c = 0;
298
299 /*
300 * REVISIT: pwrdm_wait_transition() may be better implemented
301 * via a callback and a periodic timer check -- how long do we expect
302 * powerdomain transitions to take?
303 */
304
305 /* XXX Is this udelay() value meaningful? */
306 while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
307 & OMAP_INTRANSITION_MASK) &&
308 (c++ < PWRDM_TRANSITION_BAILOUT))
309 udelay(1);
310
311 if (c > PWRDM_TRANSITION_BAILOUT) {
312 pr_err("powerdomain: %s: waited too long to complete transition\n",
313 pwrdm->name);
314 return -EAGAIN;
315 }
316
317 pr_debug("powerdomain: completed transition in %d loops\n", c);
318
319 return 0;
320}
321
322struct pwrdm_ops am33xx_pwrdm_operations = {
323 .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
324 .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
325 .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
326 .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
327 .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
328 .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
329 .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
330 .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
331 .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
332 .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
333 .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
334 .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
335 .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
336 .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
337};
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
new file mode 100644
index 000000000000..1fea656b2ca8
--- /dev/null
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -0,0 +1,403 @@
1/*
2 * OMAP3xxx PRM module functions
3 *
4 * Copyright (C) 2010-2012 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson
7 * Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/irq.h>
20
21#include "common.h"
22#include <plat/cpu.h>
23#include <plat/prcm.h>
24
25#include "vp.h"
26#include "powerdomain.h"
27#include "prm3xxx.h"
28#include "prm2xxx_3xxx.h"
29#include "cm2xxx_3xxx.h"
30#include "prm-regbits-34xx.h"
31
32static const struct omap_prcm_irq omap3_prcm_irqs[] = {
33 OMAP_PRCM_IRQ("wkup", 0, 0),
34 OMAP_PRCM_IRQ("io", 9, 1),
35};
36
37static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
38 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
39 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
40 .nr_regs = 1,
41 .irqs = omap3_prcm_irqs,
42 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
43 .irq = 11 + OMAP_INTC_START,
44 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
45 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
46 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
47 .restore_irqen = &omap3xxx_prm_restore_irqen,
48};
49
50/*
51 * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware
52 * register (which are specific to OMAP3xxx SoCs) to reset source ID
53 * bit shifts (which is an OMAP SoC-independent enumeration)
54 */
55static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = {
56 { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
57 { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
58 { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
59 { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
60 { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
61 { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
62 { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT,
63 OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
64 { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT,
65 OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
66 { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
67 { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT },
68 { -1, -1 },
69};
70
71/* PRM VP */
72
73/*
74 * struct omap3_vp - OMAP3 VP register access description.
75 * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
76 */
77struct omap3_vp {
78 u32 tranxdone_status;
79};
80
81static struct omap3_vp omap3_vp[] = {
82 [OMAP3_VP_VDD_MPU_ID] = {
83 .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
84 },
85 [OMAP3_VP_VDD_CORE_ID] = {
86 .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
87 },
88};
89
90#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
91
92u32 omap3_prm_vp_check_txdone(u8 vp_id)
93{
94 struct omap3_vp *vp = &omap3_vp[vp_id];
95 u32 irqstatus;
96
97 irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
98 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
99 return irqstatus & vp->tranxdone_status;
100}
101
102void omap3_prm_vp_clear_txdone(u8 vp_id)
103{
104 struct omap3_vp *vp = &omap3_vp[vp_id];
105
106 omap2_prm_write_mod_reg(vp->tranxdone_status,
107 OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
108}
109
110u32 omap3_prm_vcvp_read(u8 offset)
111{
112 return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
113}
114
115void omap3_prm_vcvp_write(u32 val, u8 offset)
116{
117 omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
118}
119
120u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
121{
122 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
123}
124
125/**
126 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
127 * @events: ptr to a u32, preallocated by caller
128 *
129 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
130 * MPU IRQs, and store the result into the u32 pointed to by @events.
131 * No return value.
132 */
133void omap3xxx_prm_read_pending_irqs(unsigned long *events)
134{
135 u32 mask, st;
136
137 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
138 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
139 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
140
141 events[0] = mask & st;
142}
143
144/**
145 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
146 *
147 * Force any buffered writes to the PRM IP block to complete. Needed
148 * by the PRM IRQ handler, which reads and writes directly to the IP
149 * block, to avoid race conditions after acknowledging or clearing IRQ
150 * bits. No return value.
151 */
152void omap3xxx_prm_ocp_barrier(void)
153{
154 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
155}
156
157/**
158 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
159 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
160 *
161 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
162 * must be allocated by the caller. Intended to be used in the PRM
163 * interrupt handler suspend callback. The OCP barrier is needed to
164 * ensure the write to disable PRM interrupts reaches the PRM before
165 * returning; otherwise, spurious interrupts might occur. No return
166 * value.
167 */
168void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
169{
170 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
171 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
172 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
173
174 /* OCP barrier */
175 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
176}
177
178/**
179 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
180 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
181 *
182 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
183 * to be used in the PRM interrupt handler resume callback to restore
184 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
185 * barrier should be needed here; any pending PRM interrupts will fire
186 * once the writes reach the PRM. No return value.
187 */
188void omap3xxx_prm_restore_irqen(u32 *saved_mask)
189{
190 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
191 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
192}
193
194/**
195 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
196 *
197 * Clear any previously-latched I/O wakeup events and ensure that the
198 * I/O wakeup gates are aligned with the current mux settings. Works
199 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
200 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
201 * return value.
202 */
203void omap3xxx_prm_reconfigure_io_chain(void)
204{
205 int i = 0;
206
207 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
208 PM_WKEN);
209
210 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
211 OMAP3430_ST_IO_CHAIN_MASK,
212 MAX_IOPAD_LATCH_TIME, i);
213 if (i == MAX_IOPAD_LATCH_TIME)
214 pr_warn("PRM: I/O chain clock line assertion timed out\n");
215
216 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
217 PM_WKEN);
218
219 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
220 PM_WKST);
221
222 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
223}
224
225/**
226 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
227 *
228 * Activates the I/O wakeup event latches and allows events logged by
229 * those latches to signal a wakeup event to the PRCM. For I/O
230 * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
231 * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
232 * No return value.
233 */
234static void __init omap3xxx_prm_enable_io_wakeup(void)
235{
236 if (omap3_has_io_wakeup())
237 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
238 PM_WKEN);
239}
240
241/**
242 * omap3xxx_prm_read_reset_sources - return the last SoC reset source
243 *
244 * Return a u32 representing the last reset sources of the SoC. The
245 * returned reset source bits are standardized across OMAP SoCs.
246 */
247static u32 omap3xxx_prm_read_reset_sources(void)
248{
249 struct prm_reset_src_map *p;
250 u32 r = 0;
251 u32 v;
252
253 v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
254
255 p = omap3xxx_prm_reset_src_map;
256 while (p->reg_shift >= 0 && p->std_shift >= 0) {
257 if (v & (1 << p->reg_shift))
258 r |= 1 << p->std_shift;
259 p++;
260 }
261
262 return r;
263}
264
265/* Powerdomain low-level functions */
266
267/* Applicable only for OMAP3. Not supported on OMAP2 */
268static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
269{
270 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
271 OMAP3430_PM_PREPWSTST,
272 OMAP3430_LASTPOWERSTATEENTERED_MASK);
273}
274
275static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
276{
277 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
278 OMAP2_PM_PWSTST,
279 OMAP3430_LOGICSTATEST_MASK);
280}
281
282static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
283{
284 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
285 OMAP2_PM_PWSTCTRL,
286 OMAP3430_LOGICSTATEST_MASK);
287}
288
289static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
290{
291 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
292 OMAP3430_PM_PREPWSTST,
293 OMAP3430_LASTLOGICSTATEENTERED_MASK);
294}
295
296static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
297{
298 switch (bank) {
299 case 0:
300 return OMAP3430_LASTMEM1STATEENTERED_MASK;
301 case 1:
302 return OMAP3430_LASTMEM2STATEENTERED_MASK;
303 case 2:
304 return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
305 case 3:
306 return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
307 default:
308 WARN_ON(1); /* should never happen */
309 return -EEXIST;
310 }
311 return 0;
312}
313
314static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
315{
316 u32 m;
317
318 m = omap3_get_mem_bank_lastmemst_mask(bank);
319
320 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
321 OMAP3430_PM_PREPWSTST, m);
322}
323
324static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
325{
326 omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
327 return 0;
328}
329
330static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
331{
332 return omap2_prm_rmw_mod_reg_bits(0,
333 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
334 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
335}
336
337static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
338{
339 return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
340 0, pwrdm->prcm_offs,
341 OMAP2_PM_PWSTCTRL);
342}
343
344struct pwrdm_ops omap3_pwrdm_operations = {
345 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
346 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
347 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
348 .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
349 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
350 .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
351 .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
352 .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
353 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
354 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
355 .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
356 .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
357 .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
358 .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
359 .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
360 .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
361 .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
362};
363
364/*
365 *
366 */
367
368static struct prm_ll_data omap3xxx_prm_ll_data = {
369 .read_reset_sources = &omap3xxx_prm_read_reset_sources,
370};
371
372static int __init omap3xxx_prm_init(void)
373{
374 int ret;
375
376 if (!cpu_is_omap34xx())
377 return 0;
378
379 ret = prm_register(&omap3xxx_prm_ll_data);
380 if (ret)
381 return ret;
382
383 omap3xxx_prm_enable_io_wakeup();
384 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
385 if (!ret)
386 irq_set_status_flags(omap_prcm_event_to_irq("io"),
387 IRQ_NOAUTOEN);
388
389
390 return ret;
391}
392subsys_initcall(omap3xxx_prm_init);
393
394static void __exit omap3xxx_prm_exit(void)
395{
396 if (!cpu_is_omap34xx())
397 return;
398
399 /* Should never happen */
400 WARN(prm_unregister(&omap3xxx_prm_ll_data),
401 "%s: prm_ll_data function pointer mismatch\n", __func__);
402}
403__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..a3c28a875410
--- /dev/null
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -0,0 +1,160 @@
1/*
2 * OMAP3xxx Power/Reset Management (PRM) register definitions
3 *
4 * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Paul Walmsley
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The PRM hardware modules on the OMAP2/3 are quite similar to each
13 * other. The PRM on OMAP4 has a new register layout, and is handled
14 * in a separate file.
15 */
16#ifndef __ARCH_ARM_MACH_OMAP2_PRM3XXX_H
17#define __ARCH_ARM_MACH_OMAP2_PRM3XXX_H
18
19#include "prcm-common.h"
20#include "prm.h"
21#include "prm2xxx_3xxx.h"
22
23#define OMAP34XX_PRM_REGADDR(module, reg) \
24 OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
25
26
27/*
28 * OMAP3-specific global PRM registers
29 * Use __raw_{read,write}l() with these registers.
30 *
31 * With a few exceptions, these are the register names beginning with
32 * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE
33 * bits.)
34 */
35
36#define OMAP3_PRM_REVISION_OFFSET 0x0004
37#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
38#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
39#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
40
41#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
42#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
43#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
44#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
45
46
47#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
48#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
49#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
50#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
51#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
52#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
53#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
54#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
55#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
56#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
57#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
58#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
59#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
60#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
61#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
62#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
63#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
64#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
65#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
66#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
67#define OMAP3_PRM_RSTST_OFFSET 0x0058
68#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
69#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
70#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
71#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
72#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
73#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
74#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
75#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
76#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
77#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
78#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
79#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
80#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
81#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
82#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
83#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
84#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
85#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
86#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
87#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
88#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
89#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
90#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
91#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
92#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
93#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
94#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
95#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
96#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
97#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
98#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
99#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
100#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
101#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
102#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
103#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
104#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
105#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
106#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
107#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
108#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
109
110#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
111#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
112#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
113#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
114
115/* OMAP3 specific register offsets */
116#define OMAP3430ES2_PM_WKEN3 0x00f0
117#define OMAP3430ES2_PM_WKST3 0x00b8
118
119#define OMAP3430_PM_MPUGRPSEL 0x00a4
120#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
121#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
122
123#define OMAP3430_PM_IVAGRPSEL 0x00a8
124#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
125#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
126
127#define OMAP3430_PM_PREPWSTST 0x00e8
128
129#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
130#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
131
132
133#ifndef __ASSEMBLER__
134
135/* OMAP3-specific VP functions */
136u32 omap3_prm_vp_check_txdone(u8 vp_id);
137void omap3_prm_vp_clear_txdone(u8 vp_id);
138
139/*
140 * OMAP3 access functions for voltage controller (VC) and
141 * voltage proccessor (VP) in the PRM.
142 */
143extern u32 omap3_prm_vcvp_read(u8 offset);
144extern void omap3_prm_vcvp_write(u32 val, u8 offset);
145extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
146
147extern void omap3xxx_prm_reconfigure_io_chain(void);
148
149/* PRM interrupt-related functions */
150extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
151extern void omap3xxx_prm_ocp_barrier(void);
152extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
153extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
154
155extern u32 omap3xxx_prm_get_reset_sources(void);
156
157#endif /* __ASSEMBLER */
158
159
160#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index f0c4d5f4a174..a799e9552fbf 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -1,10 +1,11 @@
1/* 1/*
2 * OMAP4 PRM module functions 2 * OMAP4 PRM module functions
3 * 3 *
4 * Copyright (C) 2011 Texas Instruments, Inc. 4 * Copyright (C) 2011-2012 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation 5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson 6 * Benoît Cousson
7 * Paul Walmsley 7 * Paul Walmsley
8 * Rajendra Nayak <rnayak@ti.com>
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -27,6 +28,9 @@
27#include "prm-regbits-44xx.h" 28#include "prm-regbits-44xx.h"
28#include "prcm44xx.h" 29#include "prcm44xx.h"
29#include "prminst44xx.h" 30#include "prminst44xx.h"
31#include "powerdomain.h"
32
33/* Static data */
30 34
31static const struct omap_prcm_irq omap4_prcm_irqs[] = { 35static const struct omap_prcm_irq omap4_prcm_irqs[] = {
32 OMAP_PRCM_IRQ("wkup", 0, 0), 36 OMAP_PRCM_IRQ("wkup", 0, 0),
@@ -46,6 +50,33 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
46 .restore_irqen = &omap44xx_prm_restore_irqen, 50 .restore_irqen = &omap44xx_prm_restore_irqen,
47}; 51};
48 52
53/*
54 * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
55 * hardware register (which are specific to OMAP44xx SoCs) to reset
56 * source ID bit shifts (which is an OMAP SoC-independent
57 * enumeration)
58 */
59static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
60 { OMAP4430_RST_GLOBAL_WARM_SW_SHIFT,
61 OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
62 { OMAP4430_RST_GLOBAL_COLD_SW_SHIFT,
63 OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
64 { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT,
65 OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
66 { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
67 { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
68 { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
69 { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT,
70 OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
71 { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT,
72 OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT },
73 { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT,
74 OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
75 { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
76 { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT },
77 { -1, -1 },
78};
79
49/* PRM low-level functions */ 80/* PRM low-level functions */
50 81
51/* Read a register in a CM/PRM instance in the PRM module */ 82/* Read a register in a CM/PRM instance in the PRM module */
@@ -291,12 +322,324 @@ static void __init omap44xx_prm_enable_io_wakeup(void)
291 OMAP4_PRM_IO_PMCTRL_OFFSET); 322 OMAP4_PRM_IO_PMCTRL_OFFSET);
292} 323}
293 324
294static int __init omap4xxx_prcm_init(void) 325/**
326 * omap44xx_prm_read_reset_sources - return the last SoC reset source
327 *
328 * Return a u32 representing the last reset sources of the SoC. The
329 * returned reset source bits are standardized across OMAP SoCs.
330 */
331static u32 omap44xx_prm_read_reset_sources(void)
332{
333 struct prm_reset_src_map *p;
334 u32 r = 0;
335 u32 v;
336
337 v = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
338 OMAP4_RM_RSTST);
339
340 p = omap44xx_prm_reset_src_map;
341 while (p->reg_shift >= 0 && p->std_shift >= 0) {
342 if (v & (1 << p->reg_shift))
343 r |= 1 << p->std_shift;
344 p++;
345 }
346
347 return r;
348}
349
350/* Powerdomain low-level functions */
351
352static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
353{
354 omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
355 (pwrst << OMAP_POWERSTATE_SHIFT),
356 pwrdm->prcm_partition,
357 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
358 return 0;
359}
360
361static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
362{
363 u32 v;
364
365 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
366 OMAP4_PM_PWSTCTRL);
367 v &= OMAP_POWERSTATE_MASK;
368 v >>= OMAP_POWERSTATE_SHIFT;
369
370 return v;
371}
372
373static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
374{
375 u32 v;
376
377 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
378 OMAP4_PM_PWSTST);
379 v &= OMAP_POWERSTATEST_MASK;
380 v >>= OMAP_POWERSTATEST_SHIFT;
381
382 return v;
383}
384
385static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
386{
387 u32 v;
388
389 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
390 OMAP4_PM_PWSTST);
391 v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
392 v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
393
394 return v;
395}
396
397static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
398{
399 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
400 (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
401 pwrdm->prcm_partition,
402 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
403 return 0;
404}
405
406static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
407{
408 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
409 OMAP4430_LASTPOWERSTATEENTERED_MASK,
410 pwrdm->prcm_partition,
411 pwrdm->prcm_offs, OMAP4_PM_PWSTST);
412 return 0;
413}
414
415static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
416{
417 u32 v;
418
419 v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
420 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
421 pwrdm->prcm_partition, pwrdm->prcm_offs,
422 OMAP4_PM_PWSTCTRL);
423
424 return 0;
425}
426
427static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
428 u8 pwrst)
429{
430 u32 m;
431
432 m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
433
434 omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
435 pwrdm->prcm_partition, pwrdm->prcm_offs,
436 OMAP4_PM_PWSTCTRL);
437
438 return 0;
439}
440
441static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
442 u8 pwrst)
443{
444 u32 m;
445
446 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
447
448 omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
449 pwrdm->prcm_partition, pwrdm->prcm_offs,
450 OMAP4_PM_PWSTCTRL);
451
452 return 0;
453}
454
455static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
456{
457 u32 v;
458
459 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
460 OMAP4_PM_PWSTST);
461 v &= OMAP4430_LOGICSTATEST_MASK;
462 v >>= OMAP4430_LOGICSTATEST_SHIFT;
463
464 return v;
465}
466
467static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
295{ 468{
296 if (cpu_is_omap44xx()) { 469 u32 v;
297 omap44xx_prm_enable_io_wakeup(); 470
298 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); 471 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
472 OMAP4_PM_PWSTCTRL);
473 v &= OMAP4430_LOGICRETSTATE_MASK;
474 v >>= OMAP4430_LOGICRETSTATE_SHIFT;
475
476 return v;
477}
478
479/**
480 * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
481 * @pwrdm: struct powerdomain * to read the state for
482 *
483 * Reads the previous logic powerstate for a powerdomain. This
484 * function must determine the previous logic powerstate by first
485 * checking the previous powerstate for the domain. If that was OFF,
486 * then logic has been lost. If previous state was RETENTION, the
487 * function reads the setting for the next retention logic state to
488 * see the actual value. In every other case, the logic is
489 * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
490 * depending whether the logic was retained or not.
491 */
492static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
493{
494 int state;
495
496 state = omap4_pwrdm_read_prev_pwrst(pwrdm);
497
498 if (state == PWRDM_POWER_OFF)
499 return PWRDM_POWER_OFF;
500
501 if (state != PWRDM_POWER_RET)
502 return PWRDM_POWER_RET;
503
504 return omap4_pwrdm_read_logic_retst(pwrdm);
505}
506
507static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
508{
509 u32 m, v;
510
511 m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
512
513 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
514 OMAP4_PM_PWSTST);
515 v &= m;
516 v >>= __ffs(m);
517
518 return v;
519}
520
521static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
522{
523 u32 m, v;
524
525 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
526
527 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
528 OMAP4_PM_PWSTCTRL);
529 v &= m;
530 v >>= __ffs(m);
531
532 return v;
533}
534
535/**
536 * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
537 * @pwrdm: struct powerdomain * to read mem powerstate for
538 * @bank: memory bank index
539 *
540 * Reads the previous memory powerstate for a powerdomain. This
541 * function must determine the previous memory powerstate by first
542 * checking the previous powerstate for the domain. If that was OFF,
543 * then logic has been lost. If previous state was RETENTION, the
544 * function reads the setting for the next memory retention state to
545 * see the actual value. In every other case, the logic is
546 * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
547 * depending whether logic was retained or not.
548 */
549static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
550{
551 int state;
552
553 state = omap4_pwrdm_read_prev_pwrst(pwrdm);
554
555 if (state == PWRDM_POWER_OFF)
556 return PWRDM_POWER_OFF;
557
558 if (state != PWRDM_POWER_RET)
559 return PWRDM_POWER_RET;
560
561 return omap4_pwrdm_read_mem_retst(pwrdm, bank);
562}
563
564static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
565{
566 u32 c = 0;
567
568 /*
569 * REVISIT: pwrdm_wait_transition() may be better implemented
570 * via a callback and a periodic timer check -- how long do we expect
571 * powerdomain transitions to take?
572 */
573
574 /* XXX Is this udelay() value meaningful? */
575 while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
576 pwrdm->prcm_offs,
577 OMAP4_PM_PWSTST) &
578 OMAP_INTRANSITION_MASK) &&
579 (c++ < PWRDM_TRANSITION_BAILOUT))
580 udelay(1);
581
582 if (c > PWRDM_TRANSITION_BAILOUT) {
583 pr_err("powerdomain: %s: waited too long to complete transition\n",
584 pwrdm->name);
585 return -EAGAIN;
299 } 586 }
587
588 pr_debug("powerdomain: completed transition in %d loops\n", c);
589
300 return 0; 590 return 0;
301} 591}
302subsys_initcall(omap4xxx_prcm_init); 592
593struct pwrdm_ops omap4_pwrdm_operations = {
594 .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
595 .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
596 .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
597 .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
598 .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
599 .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
600 .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
601 .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
602 .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst,
603 .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
604 .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
605 .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
606 .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
607 .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
608 .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
609 .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
610};
611
612/*
613 * XXX document
614 */
615static struct prm_ll_data omap44xx_prm_ll_data = {
616 .read_reset_sources = &omap44xx_prm_read_reset_sources,
617};
618
619static int __init omap44xx_prm_init(void)
620{
621 int ret;
622
623 if (!cpu_is_omap44xx())
624 return 0;
625
626 ret = prm_register(&omap44xx_prm_ll_data);
627 if (ret)
628 return ret;
629
630 omap44xx_prm_enable_io_wakeup();
631
632 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
633}
634subsys_initcall(omap44xx_prm_init);
635
636static void __exit omap44xx_prm_exit(void)
637{
638 if (!cpu_is_omap44xx())
639 return;
640
641 /* Should never happen */
642 WARN(prm_unregister(&omap44xx_prm_ll_data),
643 "%s: prm_ll_data function pointer mismatch\n", __func__);
644}
645__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);
771extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); 771extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
772extern void omap44xx_prm_restore_irqen(u32 *saved_mask); 772extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
773 773
774extern u32 omap44xx_prm_get_reset_sources(void);
775
774# endif 776# endif
775 777
776#endif 778#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 6fabbd816d6b..6c595798c5c5 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -28,6 +28,8 @@
28#include <plat/prcm.h> 28#include <plat/prcm.h>
29 29
30#include "prm2xxx_3xxx.h" 30#include "prm2xxx_3xxx.h"
31#include "prm2xxx.h"
32#include "prm3xxx.h"
31#include "prm44xx.h" 33#include "prm44xx.h"
32 34
33/* 35/*
@@ -53,6 +55,13 @@ static struct irq_chip_generic **prcm_irq_chips;
53 */ 55 */
54static struct omap_prcm_irq_setup *prcm_irq_setup; 56static struct omap_prcm_irq_setup *prcm_irq_setup;
55 57
58/*
59 * prm_ll_data: function pointers to SoC-specific implementations of
60 * common PRM functions
61 */
62static struct prm_ll_data null_prm_ll_data;
63static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;
64
56/* Private functions */ 65/* Private functions */
57 66
58/* 67/*
@@ -319,64 +328,71 @@ err:
319 return -ENOMEM; 328 return -ENOMEM;
320} 329}
321 330
322/* 331/**
323 * Stubbed functions so that common files continue to build when 332 * prm_read_reset_sources - return the sources of the SoC's last reset
324 * custom builds are used 333 *
325 * XXX These are temporary and should be removed at the earliest possible 334 * Return a u32 bitmask representing the reset sources that caused the
326 * opportunity 335 * SoC to reset. The low-level per-SoC functions called by this
336 * function remap the SoC-specific reset source bits into an
337 * OMAP-common set of reset source bits, defined in
338 * arch/arm/mach-omap2/prm.h. Returns the standardized reset source
339 * u32 bitmask from the hardware upon success, or returns (1 <<
340 * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
341 * function was registered.
327 */ 342 */
328u32 __weak omap2_prm_read_mod_reg(s16 module, u16 idx) 343u32 prm_read_reset_sources(void)
329{ 344{
330 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); 345 u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;
331 return 0;
332}
333 346
334void __weak omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) 347 if (prm_ll_data->read_reset_sources)
335{ 348 ret = prm_ll_data->read_reset_sources();
336 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); 349 else
337} 350 WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);
338 351
339u32 __weak omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, 352 return ret;
340 s16 module, s16 idx)
341{
342 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
343 return 0;
344} 353}
345 354
346u32 __weak omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) 355/**
356 * prm_register - register per-SoC low-level data with the PRM
357 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
358 *
359 * Register per-SoC low-level OMAP PRM data and function pointers with
360 * the OMAP PRM common interface. The caller must keep the data
361 * pointed to by @pld valid until it calls prm_unregister() and
362 * it returns successfully. Returns 0 upon success, -EINVAL if @pld
363 * is NULL, or -EEXIST if prm_register() has already been called
364 * without an intervening prm_unregister().
365 */
366int prm_register(struct prm_ll_data *pld)
347{ 367{
348 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); 368 if (!pld)
349 return 0; 369 return -EINVAL;
350}
351 370
352u32 __weak omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) 371 if (prm_ll_data != &null_prm_ll_data)
353{ 372 return -EEXIST;
354 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
355 return 0;
356}
357 373
358u32 __weak omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) 374 prm_ll_data = pld;
359{
360 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
361 return 0;
362}
363 375
364int __weak omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
365{
366 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
367 return 0; 376 return 0;
368} 377}
369 378
370int __weak omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) 379/**
380 * prm_unregister - unregister per-SoC low-level data & function pointers
381 * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
382 *
383 * Unregister per-SoC low-level OMAP PRM data and function pointers
384 * that were previously registered with prm_register(). The
385 * caller may not destroy any of the data pointed to by @pld until
386 * this function returns successfully. Returns 0 upon success, or
387 * -EINVAL if @pld is NULL or if @pld does not match the struct
388 * prm_ll_data * previously registered by prm_register().
389 */
390int prm_unregister(struct prm_ll_data *pld)
371{ 391{
372 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); 392 if (!pld || prm_ll_data != pld)
373 return 0; 393 return -EINVAL;
374} 394
395 prm_ll_data = &null_prm_ll_data;
375 396
376int __weak omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
377 u8 st_shift)
378{
379 WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
380 return 0; 397 return 0;
381} 398}
382
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
index 3b8bfdf848d5..26c1728e09ca 100644
--- a/arch/arm/mach-omap2/sdrc2xxx.c
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -29,7 +29,7 @@
29#include "soc.h" 29#include "soc.h"
30#include "iomap.h" 30#include "iomap.h"
31#include "common.h" 31#include "common.h"
32#include "prm2xxx_3xxx.h" 32#include "prm2xxx.h"
33#include "clock.h" 33#include "clock.h"
34#include "sdrc.h" 34#include "sdrc.h"
35 35
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 75afe11207ff..474dba7263e3 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -30,8 +30,8 @@
30 30
31#include "omap34xx.h" 31#include "omap34xx.h"
32#include "iomap.h" 32#include "iomap.h"
33#include "cm2xxx_3xxx.h" 33#include "cm3xxx.h"
34#include "prm2xxx_3xxx.h" 34#include "prm3xxx.h"
35#include "sdrc.h" 35#include "sdrc.h"
36#include "control.h" 36#include "control.h"
37 37
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 @@
34 34
35#include "soc.h" 35#include "soc.h"
36#include "iomap.h" 36#include "iomap.h"
37#include "prm2xxx_3xxx.h" 37#include "prm2xxx.h"
38#include "cm2xxx_3xxx.h" 38#include "cm2xxx.h"
39#include "sdrc.h" 39#include "sdrc.h"
40 40
41 .text 41 .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 @@
34 34
35#include "soc.h" 35#include "soc.h"
36#include "iomap.h" 36#include "iomap.h"
37#include "prm2xxx_3xxx.h" 37#include "prm2xxx.h"
38#include "cm2xxx_3xxx.h" 38#include "cm2xxx.h"
39#include "sdrc.h" 39#include "sdrc.h"
40 40
41 .text 41 .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 @@
32#include "soc.h" 32#include "soc.h"
33#include "iomap.h" 33#include "iomap.h"
34#include "sdrc.h" 34#include "sdrc.h"
35#include "cm2xxx_3xxx.h" 35#include "cm3xxx.h"
36 36
37/* 37/*
38 * This file needs be built unconditionally as ARM to interoperate correctly 38 * This file needs be built unconditionally as ARM to interoperate correctly