diff options
author | Olof Johansson <olof@lixom.net> | 2012-11-05 13:52:03 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-11-05 13:52:03 -0500 |
commit | 976669971ff7d2d668ee3d9e92d0d9db5aae847c (patch) | |
tree | e696fcf3eb3b9c6311fc4fa51aa8c89a29aad9c2 /arch | |
parent | 9237b5aa447dce55913b61f435c5140410bf5310 (diff) | |
parent | 7fc54fd3084457c7f11b9e2e1e3fcd19a3badc33 (diff) |
Merge tag 'omap-for-v3.8/cleanup-prcm-part1-take2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/headers
From Paul Walmsley <paul@pwsan.com> via Tony Lindgren:
The first set of OMAP PRM/CM-related cleanup patches for 3.8.
Prepares for the future move of the PRM/CM code to drivers/. Also
includes some prcm.[ch] cleanup patches from the WDTIMER cleanup
series that don't need external acks.
* tag 'omap-for-v3.8/cleanup-prcm-part1-take2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
ARM: OMAP2+: PRM: create PRM reset source API for the watchdog timer driver
ARM: OMAP1: create read_reset_sources() function (for initial use by watchdog)
ARM: OMAP2+: CM: prepare for use of cm_ll_data function pointers
ARM: OMAP2+: PRM: prepare for use of prm_ll_data function pointers
ARM: OMAP2/3: clockdomain/PRM/CM: move the low-level clockdomain functions into PRM/CM
ARM: OMAP2+: CM/hwmod: split CM functions into OMAP2, OMAP3-specific files
ARM: OMAP2+: powerdomain/PRM: move the low-level powerdomain functions into PRM
ARM: OMAP2+: PRM: split PRM functions into OMAP2, OMAP3-specific files
ARM: OMAP2+: PRM: remove PRM weak functions
Diffstat (limited to 'arch')
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); | |||
94 | static inline int ocpi_enable(void) { return 0; } | 94 | static inline int ocpi_enable(void) { return 0; } |
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | extern 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 | |||
13 | void omap1_restart(char mode, const char *cmd) | 26 | void 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 | */ | ||
46 | int 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/ | 10 | omap-2-3-common = irq.o |
11 | obj-$(CONFIG_ARCH_OMAP2) += irq.o | 11 | hwmod-common = omap_hwmod.o \ |
12 | obj-$(CONFIG_ARCH_OMAP3) += irq.o | 12 | omap_hwmod_common_data.o |
13 | obj-$(CONFIG_SOC_AM33XX) += irq.o | 13 | clock-common = clock.o clock_common_data.o \ |
14 | 14 | clkt_dpll.o clkt_clksel.o | |
15 | # Secure monitor API support | 15 | secure-common = omap-smc.o omap-secure.o |
16 | obj-$(CONFIG_ARCH_OMAP3) += omap-smc.o omap-secure.o | 16 | |
17 | obj-$(CONFIG_ARCH_OMAP4) += omap-smc.o omap-secure.o | 17 | obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) |
18 | obj-$(CONFIG_SOC_OMAP5) += omap-smc.o omap-secure.o | 18 | obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) |
19 | obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common) | ||
20 | obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common) | ||
21 | obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common) | ||
19 | 22 | ||
20 | ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) | 23 | ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) |
21 | obj-y += mcbsp.o | 24 | obj-y += mcbsp.o |
22 | endif | 25 | endif |
23 | 26 | ||
24 | obj-$(CONFIG_TWL4030_CORE) += omap_twl.o | 27 | obj-$(CONFIG_TWL4030_CORE) += omap_twl.o |
28 | obj-$(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 | ||
28 | obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o | 32 | obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o |
29 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o | 33 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o |
30 | obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o | 34 | omap-4-5-common = omap4-common.o omap-wakeupgen.o \ |
31 | obj-$(CONFIG_SOC_OMAP5) += omap4-common.o omap-wakeupgen.o | 35 | sleep44xx.o |
36 | obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common) | ||
37 | obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common) | ||
32 | 38 | ||
33 | plus_sec := $(call as-instr,.arch_extension sec,+sec) | 39 | plus_sec := $(call as-instr,.arch_extension sec,+sec) |
34 | AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) | 40 | AFLAGS_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 |
54 | obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o | 60 | obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o |
55 | # obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o | 61 | # obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o |
56 | obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o | ||
57 | 62 | ||
58 | # OPP table initialization | 63 | # OPP table initialization |
59 | ifeq ($(CONFIG_PM_OPP),y) | 64 | ifeq ($(CONFIG_PM_OPP),y) |
@@ -64,15 +69,15 @@ endif | |||
64 | 69 | ||
65 | # Power Management | 70 | # Power Management |
66 | ifeq ($(CONFIG_PM),y) | 71 | ifeq ($(CONFIG_PM),y) |
67 | obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o sleep24xx.o | 72 | obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o |
73 | obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o | ||
68 | obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o | 74 | obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o |
69 | obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o | 75 | obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o |
70 | obj-$(CONFIG_ARCH_OMAP4) += sleep44xx.o | 76 | obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o |
71 | obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o sleep44xx.o | ||
72 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o | 77 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o |
73 | 78 | ||
74 | obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o | 79 | obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o |
75 | obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o | 80 | obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o |
76 | 81 | ||
77 | AFLAGS_sleep24xx.o :=-Wa,-march=armv6 | 82 | AFLAGS_sleep24xx.o :=-Wa,-march=armv6 |
78 | AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) | 83 | AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) |
@@ -84,76 +89,82 @@ endif | |||
84 | endif | 89 | endif |
85 | 90 | ||
86 | ifeq ($(CONFIG_CPU_IDLE),y) | 91 | ifeq ($(CONFIG_CPU_IDLE),y) |
87 | obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o | 92 | obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o |
88 | obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o | 93 | obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o |
89 | endif | 94 | endif |
90 | 95 | ||
91 | # PRCM | 96 | # PRCM |
92 | obj-y += prcm.o prm_common.o | 97 | obj-y += prcm.o prm_common.o cm_common.o |
93 | obj-$(CONFIG_ARCH_OMAP2) += cm2xxx_3xxx.o prm2xxx_3xxx.o | 98 | obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o |
94 | obj-$(CONFIG_ARCH_OMAP3) += cm2xxx_3xxx.o prm2xxx_3xxx.o | 99 | obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o |
95 | obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o | 100 | obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o |
96 | obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o | 101 | obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o |
97 | omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ | 102 | omap-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 | ||
101 | obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) | 105 | obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) |
102 | obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common) | 106 | obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common) |
103 | 107 | ||
104 | # OMAP voltage domains | 108 | # OMAP voltage domains |
105 | obj-y += voltage.o vc.o vp.o | 109 | voltagedomain-common := voltage.o vc.o vp.o |
110 | obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) | ||
106 | obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o | 111 | obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o |
112 | obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) | ||
107 | obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o | 113 | obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o |
114 | obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) | ||
108 | obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o | 115 | obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o |
109 | obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o | 116 | obj-$(CONFIG_SOC_AM33XX) += $(voltagedomain-common) |
117 | obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o | ||
118 | obj-$(CONFIG_SOC_OMAP5) += $(voltagedomain-common) | ||
110 | 119 | ||
111 | # OMAP powerdomain framework | 120 | # OMAP powerdomain framework |
112 | obj-y += powerdomain.o powerdomain-common.o | 121 | powerdomain-common += powerdomain.o powerdomain-common.o |
122 | obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) | ||
113 | obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o | 123 | obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o |
114 | obj-$(CONFIG_ARCH_OMAP2) += powerdomain2xxx_3xxx.o | ||
115 | obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o | 124 | obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o |
116 | obj-$(CONFIG_ARCH_OMAP3) += powerdomain2xxx_3xxx.o | 125 | obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) |
117 | obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o | 126 | obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o |
118 | obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o | 127 | obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o |
119 | obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o | 128 | obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) |
120 | obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o | 129 | obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o |
121 | obj-$(CONFIG_SOC_AM33XX) += powerdomain33xx.o | 130 | obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common) |
122 | obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o | 131 | obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o |
123 | obj-$(CONFIG_SOC_OMAP5) += powerdomain44xx.o | 132 | obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common) |
124 | 133 | ||
125 | # PRCM clockdomain control | 134 | # PRCM clockdomain control |
126 | obj-y += clockdomain.o | 135 | clockdomain-common += clockdomain.o |
127 | obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o | 136 | obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) |
128 | obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o | 137 | obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o |
129 | obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o | 138 | obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o |
130 | obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o | 139 | obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o |
131 | obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o | 140 | obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) |
132 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o | 141 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o |
133 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o | 142 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o |
134 | obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o | 143 | obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) |
135 | obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o | 144 | obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o |
136 | obj-$(CONFIG_SOC_AM33XX) += clockdomain33xx.o | 145 | obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common) |
137 | obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o | 146 | obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o |
138 | obj-$(CONFIG_SOC_OMAP5) += clockdomain44xx.o | 147 | obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common) |
139 | 148 | ||
140 | # Clock framework | 149 | # Clock framework |
141 | obj-y += clock.o clock_common_data.o \ | 150 | obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o |
142 | clkt_dpll.o clkt_clksel.o | 151 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o |
143 | obj-$(CONFIG_ARCH_OMAP2) += clock2xxx.o | 152 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o |
144 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o clkt2xxx_sys.o | ||
145 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o | 153 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o |
146 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o | 154 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o |
147 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o | 155 | obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o |
148 | obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o | 156 | obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o |
149 | obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o | 157 | obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o |
150 | obj-$(CONFIG_ARCH_OMAP3) += clock3xxx.o | 158 | obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o |
151 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o | 159 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o |
152 | obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o clkt_iclk.o | 160 | obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o |
153 | obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o | 161 | obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o |
154 | obj-$(CONFIG_ARCH_OMAP4) += clock44xx_data.o | 162 | obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o |
163 | obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o | ||
155 | obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o | 164 | obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o |
156 | obj-$(CONFIG_SOC_AM33XX) += dpll3xxx.o clock33xx_data.o | 165 | obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o |
166 | obj-$(CONFIG_SOC_AM33XX) += clock33xx_data.o | ||
167 | obj-$(CONFIG_SOC_OMAP5) += $(clock-common) | ||
157 | obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o | 168 | obj-$(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 | |||
161 | obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o | 172 | obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o |
162 | 173 | ||
163 | # hwmod data | 174 | # hwmod data |
164 | obj-y += omap_hwmod_common_data.o | ||
165 | obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o | 175 | obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o |
166 | obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o | 176 | obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o |
167 | obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o | 177 | obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o |
@@ -207,10 +217,10 @@ obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o | |||
207 | obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o | 217 | obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o |
208 | obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o | 218 | obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o |
209 | obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o | 219 | obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o |
210 | obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o | 220 | obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o |
211 | obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o | 221 | obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o |
212 | obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o | 222 | obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o |
213 | obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o | 223 | obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o |
214 | obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o | 224 | obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o |
215 | obj-$(CONFIG_MACH_OVERO) += board-overo.o | 225 | obj-$(CONFIG_MACH_OVERO) += board-overo.o |
216 | obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o | 226 | obj-$(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 | |||
28 | static 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 | |||
36 | static 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 | |||
44 | static 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 | |||
51 | static 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 | |||
70 | static 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 | |||
79 | static 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 | |||
88 | static 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 | |||
95 | static 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 | |||
113 | static 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 | |||
121 | static 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 | |||
129 | static 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 | |||
138 | static 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 | |||
147 | static 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 | |||
157 | static 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 | |||
167 | static 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 | |||
174 | static 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 | |||
181 | static 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 | |||
204 | static 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 | |||
227 | static 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 | |||
236 | static 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 | |||
245 | static 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 | |||
279 | static 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 | |||
313 | struct 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 | |||
326 | struct 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 | |||
25 | static 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 | |||
31 | static 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 | |||
37 | static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) | ||
38 | { | ||
39 | am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
40 | } | ||
41 | |||
42 | static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) | ||
43 | { | ||
44 | am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
45 | } | ||
46 | |||
47 | static 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 | |||
55 | static 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 | |||
67 | struct 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 | |||
20 | static 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 | |||
30 | static 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 | |||
40 | static 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 | |||
49 | static 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 | |||
71 | static 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 | |||
78 | static 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 | |||
85 | static 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 | |||
91 | static 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 | |||
101 | static 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 | |||
109 | static 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 | |||
136 | struct 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 | */ | ||
41 | struct cm_ll_data {}; | ||
42 | |||
43 | extern int cm_register(struct cm_ll_data *cld); | ||
44 | extern 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 | |||
38 | static const u8 omap2xxx_cm_idlest_offs[] = { | ||
39 | CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4 | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * | ||
44 | */ | ||
45 | |||
46 | static 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 | |||
56 | bool 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 | |||
67 | void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) | ||
68 | { | ||
69 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); | ||
70 | } | ||
71 | |||
72 | void 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 | |||
81 | static 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 | |||
91 | void omap2xxx_cm_set_dpll_disable_autoidle(void) | ||
92 | { | ||
93 | _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP); | ||
94 | } | ||
95 | |||
96 | void 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 | |||
105 | static 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 | |||
115 | void 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 | |||
121 | void 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 | |||
127 | void 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 | |||
133 | void 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 | */ | ||
153 | int 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 | |||
175 | static 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 | |||
184 | static 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 | |||
193 | static 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 | |||
218 | static 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 | |||
243 | struct 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 | |||
49 | extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); | ||
50 | extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); | ||
51 | |||
52 | extern void omap2xxx_cm_set_dpll_disable_autoidle(void); | ||
53 | extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); | ||
54 | |||
55 | extern void omap2xxx_cm_set_apll54_disable_autoidle(void); | ||
56 | extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); | ||
57 | extern void omap2xxx_cm_set_apll96_disable_autoidle(void); | ||
58 | extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); | ||
59 | |||
60 | extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); | ||
61 | extern 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 | 53 | static 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 | ||
58 | static 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 */ |
64 | static 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 | ||
108 | extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx); | 74 | return v; |
109 | extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx); | 75 | } |
110 | extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); | ||
111 | 76 | ||
112 | extern 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); | 78 | static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) |
114 | extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx); | 79 | { |
115 | extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx); | 80 | u32 v; |
116 | 81 | ||
117 | extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask); | 82 | v = omap2_cm_read_mod_reg(domain, idx); |
118 | extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); | 83 | v &= mask; |
119 | extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); | 84 | v >>= __ffs(mask); |
120 | 85 | ||
121 | extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); | 86 | return v; |
122 | extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); | 87 | } |
123 | extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); | ||
124 | extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); | ||
125 | 88 | ||
126 | extern void omap2xxx_cm_set_dpll_disable_autoidle(void); | 89 | static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) |
127 | extern 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 | ||
129 | extern void omap2xxx_cm_set_apll54_disable_autoidle(void); | 94 | static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) |
130 | extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); | 95 | { |
131 | extern void omap2xxx_cm_set_apll96_disable_autoidle(void); | 96 | return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx); |
132 | extern 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__ | ||
152 | extern void omap3_cm_save_context(void); | ||
153 | extern 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 | |||
320 | static 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 | |||
326 | static 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 | |||
332 | static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) | ||
333 | { | ||
334 | am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
335 | } | ||
336 | |||
337 | static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) | ||
338 | { | ||
339 | am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
340 | } | ||
341 | |||
342 | static 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 | |||
350 | static 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 | |||
362 | struct 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 */ | 30 | static 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 | |||
37 | static const u8 cm_idlest_offs[] = { | ||
38 | CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4 | ||
39 | }; | 32 | }; |
40 | 33 | ||
41 | u32 omap2_cm_read_mod_reg(s16 module, u16 idx) | ||
42 | { | ||
43 | return __raw_readl(cm_base + module + idx); | ||
44 | } | ||
45 | |||
46 | void 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 */ | ||
52 | u32 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 | |||
64 | u32 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 | |||
69 | u32 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 | ||
88 | bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask) | 48 | bool 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 | |||
107 | void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) | ||
108 | { | ||
109 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); | ||
110 | } | ||
111 | |||
112 | void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) | ||
113 | { | ||
114 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask); | ||
115 | } | 57 | } |
116 | 58 | ||
117 | void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) | 59 | void 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 | ||
141 | static 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 | */ | ||
93 | int 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 | ||
151 | void omap2xxx_cm_set_dpll_disable_autoidle(void) | 113 | /* Clockdomain low-level operations */ |
114 | |||
115 | static 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 | ||
156 | void omap2xxx_cm_set_dpll_auto_low_power_stop(void) | 124 | static 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 | /* | 133 | static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1, |
162 | * APLL autoidle control | 134 | struct clockdomain *clkdm2) |
163 | */ | ||
164 | |||
165 | static 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 | ||
175 | void omap2xxx_cm_set_apll54_disable_autoidle(void) | 141 | static 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 | ||
181 | void omap2xxx_cm_set_apll54_auto_low_power_stop(void) | 158 | static 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 | ||
187 | void omap2xxx_cm_set_apll96_disable_autoidle(void) | 165 | static 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 | ||
193 | void omap2xxx_cm_set_apll96_auto_low_power_stop(void) | 172 | static 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 | /** | 181 | static 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 | */ | ||
211 | int 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]; | 190 | static 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), | 226 | static 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 | ||
263 | struct 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 | ||
241 | struct omap3_cm_regs { | 283 | struct 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 | |||
72 | extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); | ||
73 | extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); | ||
74 | extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); | ||
75 | extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); | ||
76 | |||
77 | extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); | ||
78 | extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, | ||
79 | u8 idlest_shift); | ||
80 | |||
81 | extern void omap3_cm_save_context(void); | ||
82 | extern 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 | */ | ||
25 | static struct cm_ll_data null_cm_ll_data; | ||
26 | static 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 | */ | ||
39 | int 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 | */ | ||
63 | int 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 | |||
353 | static 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 | |||
363 | static 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 | |||
373 | static 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 | |||
383 | static 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 | |||
405 | static 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 | |||
412 | static 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 | |||
419 | static 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 | |||
425 | static 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 | |||
435 | static 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 | |||
443 | static 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 | |||
470 | struct 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 | */ |
2679 | static int _omap2_wait_target_ready(struct omap_hwmod *oh) | 2680 | static 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 | */ | ||
2707 | static 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 | */ |
3960 | void __init omap_hwmod_init(void) | 3988 | void __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 */ | ||
29 | static 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 | |||
37 | static 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 | |||
44 | static 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 | |||
51 | static 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 | |||
64 | static 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 | |||
77 | static 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 | |||
87 | static 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 | |||
97 | static 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 | |||
108 | static 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 */ | ||
136 | static 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 | |||
143 | static 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 | |||
150 | static 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 | |||
157 | static 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 | |||
164 | static 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 | |||
182 | static 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 | |||
192 | static 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 | |||
198 | static 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 | |||
205 | static 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 | |||
212 | struct 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 | |||
224 | struct 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 | |||
30 | static 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 | |||
38 | static 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 | |||
49 | static 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 | |||
60 | static 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 | |||
71 | static 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 | |||
79 | static 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 | |||
87 | static 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 | |||
101 | static 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 | |||
112 | static 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 | |||
127 | static 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 | |||
142 | static 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 | |||
157 | static 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 | |||
172 | static 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 | |||
187 | static 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 | |||
214 | struct 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 | |||
27 | static 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 | |||
36 | static 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 | |||
48 | static 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 | |||
60 | static 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 | |||
72 | static 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 | |||
81 | static 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 | |||
90 | static 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 | |||
102 | static 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 | |||
116 | static 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 | |||
130 | static 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 | |||
142 | static 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 | */ | ||
167 | static 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 | |||
182 | static 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 | |||
196 | static 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 | */ | ||
224 | static 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 | |||
239 | static 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 | |||
268 | struct 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 | */ | ||
88 | struct 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 | */ | ||
97 | struct prm_ll_data { | ||
98 | u32 (*read_reset_sources)(void); | ||
99 | }; | ||
100 | |||
101 | extern int prm_register(struct prm_ll_data *pld); | ||
102 | extern int prm_unregister(struct prm_ll_data *pld); | ||
103 | |||
104 | extern 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 | */ | ||
38 | static 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 | */ | ||
54 | static 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 | |||
72 | int 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 | |||
80 | int 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 | |||
88 | struct 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 | |||
104 | static struct prm_ll_data omap2xxx_prm_ll_data = { | ||
105 | .read_reset_sources = &omap2xxx_prm_read_reset_sources, | ||
106 | }; | ||
107 | |||
108 | static 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 | } | ||
115 | subsys_initcall(omap2xxx_prm_init); | ||
116 | |||
117 | static 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 */ | ||
124 | extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); | ||
125 | extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); | ||
126 | |||
127 | extern int __init prm2xxx_init(void); | ||
128 | extern 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 | |||
31 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { | ||
32 | OMAP_PRCM_IRQ("wkup", 0, 0), | ||
33 | OMAP_PRCM_IRQ("io", 9, 1), | ||
34 | }; | ||
35 | |||
36 | static 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 | |||
49 | u32 omap2_prm_read_mod_reg(s16 module, u16 idx) | ||
50 | { | ||
51 | return __raw_readl(prm_base + module + idx); | ||
52 | } | ||
53 | |||
54 | void 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 */ | ||
60 | u32 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 */ | ||
73 | u32 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 | |||
84 | u32 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 | |||
89 | u32 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 | */ |
105 | int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) | 35 | int 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 | */ | ||
187 | struct omap3_vp { | ||
188 | u32 tranxdone_status; | ||
189 | }; | ||
190 | |||
191 | static 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 | |||
202 | u32 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 | ||
212 | void omap3_prm_vp_clear_txdone(u8 vp_id) | 105 | /* Common functions across OMAP2 and OMAP3 */ |
106 | int 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 | ||
220 | u32 omap3_prm_vcvp_read(u8 offset) | 114 | int 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 | ||
225 | void omap3_prm_vcvp_write(u32 val, u8 offset) | 121 | int 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 | ||
230 | u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) | 128 | int 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 | /** | 141 | int 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 | */ | ||
243 | void 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 | /** | 154 | int 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 | */ | ||
262 | void 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 | /** | 164 | int 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 | */ | ||
278 | void 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 | /** | 174 | int 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 | */ | ||
298 | void 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 | /** | 185 | int 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 | */ | ||
313 | void 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 | /** | 212 | int 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 | */ | 220 | int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, |
344 | static 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 | |||
228 | int 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 | ||
351 | static int __init omap3xxx_prcm_init(void) | 235 | int 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 | } |
365 | subsys_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 */ |
232 | extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx); | 56 | static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) |
233 | extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx); | 57 | { |
234 | extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); | 58 | return __raw_readl(prm_base + module + idx); |
235 | extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx); | 59 | } |
236 | extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx); | 60 | |
237 | extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask); | 61 | static 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 */ | ||
67 | static 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 */ | ||
81 | static 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 | |||
92 | static 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 | |||
97 | static 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 */ |
240 | extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); | 103 | extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); |
241 | extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); | 104 | extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); |
242 | extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); | 105 | extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); |
243 | 106 | ||
244 | /* OMAP3-specific VP functions */ | 107 | extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); |
245 | u32 omap3_prm_vp_check_txdone(u8 vp_id); | 108 | extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm); |
246 | void omap3_prm_vp_clear_txdone(u8 vp_id); | 109 | extern int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm); |
247 | 110 | extern int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, | |
248 | /* | 111 | u8 pwrst); |
249 | * OMAP3 access functions for voltage controller (VC) and | 112 | extern int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, |
250 | * voltage proccessor (VP) in the PRM. | 113 | u8 pwrst); |
251 | */ | 114 | extern int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank); |
252 | extern u32 omap3_prm_vcvp_read(u8 offset); | 115 | extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank); |
253 | extern void omap3_prm_vcvp_write(u32 val, u8 offset); | 116 | extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); |
254 | extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); | 117 | extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm); |
255 | 118 | ||
256 | extern void omap3xxx_prm_reconfigure_io_chain(void); | 119 | extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, |
257 | 120 | struct clockdomain *clkdm2); | |
258 | /* PRM interrupt-related functions */ | 121 | extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, |
259 | extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); | 122 | struct clockdomain *clkdm2); |
260 | extern void omap3xxx_prm_ocp_barrier(void); | 123 | extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, |
261 | extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); | 124 | struct clockdomain *clkdm2); |
262 | extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); | 125 | extern 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 | |||
138 | static 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 | |||
146 | static 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 | |||
157 | static 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 | |||
168 | static 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 | |||
179 | static 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 | |||
187 | static 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 | |||
195 | static 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 | |||
209 | static 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 | |||
220 | static 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 | |||
235 | static 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 | |||
250 | static 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 | |||
265 | static 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 | |||
280 | static 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 | |||
295 | static 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 | |||
322 | struct 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 | |||
32 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { | ||
33 | OMAP_PRCM_IRQ("wkup", 0, 0), | ||
34 | OMAP_PRCM_IRQ("io", 9, 1), | ||
35 | }; | ||
36 | |||
37 | static 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 | */ | ||
55 | static 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 | */ | ||
77 | struct omap3_vp { | ||
78 | u32 tranxdone_status; | ||
79 | }; | ||
80 | |||
81 | static 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 | |||
92 | u32 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 | |||
102 | void 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 | |||
110 | u32 omap3_prm_vcvp_read(u8 offset) | ||
111 | { | ||
112 | return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset); | ||
113 | } | ||
114 | |||
115 | void omap3_prm_vcvp_write(u32 val, u8 offset) | ||
116 | { | ||
117 | omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset); | ||
118 | } | ||
119 | |||
120 | u32 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 | */ | ||
133 | void 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 | */ | ||
152 | void 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 | */ | ||
168 | void 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 | */ | ||
188 | void 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 | */ | ||
203 | void 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 | */ | ||
234 | static 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 | */ | ||
247 | static 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 */ | ||
268 | static 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 | |||
275 | static 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 | |||
282 | static 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 | |||
289 | static 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 | |||
296 | static 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 | |||
314 | static 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 | |||
324 | static 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 | |||
330 | static 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 | |||
337 | static 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 | |||
344 | struct 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 | |||
368 | static struct prm_ll_data omap3xxx_prm_ll_data = { | ||
369 | .read_reset_sources = &omap3xxx_prm_read_reset_sources, | ||
370 | }; | ||
371 | |||
372 | static 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 | } | ||
392 | subsys_initcall(omap3xxx_prm_init); | ||
393 | |||
394 | static 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 */ | ||
136 | u32 omap3_prm_vp_check_txdone(u8 vp_id); | ||
137 | void 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 | */ | ||
143 | extern u32 omap3_prm_vcvp_read(u8 offset); | ||
144 | extern void omap3_prm_vcvp_write(u32 val, u8 offset); | ||
145 | extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); | ||
146 | |||
147 | extern void omap3xxx_prm_reconfigure_io_chain(void); | ||
148 | |||
149 | /* PRM interrupt-related functions */ | ||
150 | extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); | ||
151 | extern void omap3xxx_prm_ocp_barrier(void); | ||
152 | extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
153 | extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); | ||
154 | |||
155 | extern 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 | ||
31 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { | 35 | static 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 | */ | ||
59 | static 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 | ||
294 | static 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 | */ | ||
331 | static 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 | |||
352 | static 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 | |||
361 | static 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 | |||
373 | static 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 | |||
385 | static 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 | |||
397 | static 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 | |||
406 | static 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 | |||
415 | static 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 | |||
427 | static 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 | |||
441 | static 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 | |||
455 | static 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 | |||
467 | static 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 | */ | ||
492 | static 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 | |||
507 | static 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 | |||
521 | static 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 | */ | ||
549 | static 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 | |||
564 | static 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 | } |
302 | subsys_initcall(omap4xxx_prcm_init); | 592 | |
593 | struct 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 | */ | ||
615 | static struct prm_ll_data omap44xx_prm_ll_data = { | ||
616 | .read_reset_sources = &omap44xx_prm_read_reset_sources, | ||
617 | }; | ||
618 | |||
619 | static 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 | } | ||
634 | subsys_initcall(omap44xx_prm_init); | ||
635 | |||
636 | static 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); | |||
771 | extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); | 771 | extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); |
772 | extern void omap44xx_prm_restore_irqen(u32 *saved_mask); | 772 | extern void omap44xx_prm_restore_irqen(u32 *saved_mask); |
773 | 773 | ||
774 | extern 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 | */ |
54 | static struct omap_prcm_irq_setup *prcm_irq_setup; | 56 | static 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 | */ | ||
62 | static struct prm_ll_data null_prm_ll_data; | ||
63 | static 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 | */ |
328 | u32 __weak omap2_prm_read_mod_reg(s16 module, u16 idx) | 343 | u32 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 | ||
334 | void __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 | ||
339 | u32 __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 | ||
346 | u32 __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 | */ | ||
366 | int 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 | ||
352 | u32 __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 | ||
358 | u32 __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 | ||
364 | int __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 | ||
370 | int __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 | */ | ||
390 | int 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 | ||
376 | int __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 |