diff options
author | Tero Kristo <t-kristo@ti.com> | 2014-10-27 11:39:23 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2014-10-27 11:39:23 -0400 |
commit | a8ae5afa5cb820afa251b9acfe3f0a938b6a6c0d (patch) | |
tree | 21d80ee4768a6ea8e9810d252a0b7e5167dc0362 /arch/arm | |
parent | 021b6ff05c4a17cb20d71c05e251ea7f80b1c516 (diff) |
ARM: OMAP4+/AM33xx: CM: add common API for cm_wait_module_idle
Adds a generic CM driver API for waiting module to enter idle / standby.
The SoC specific implementations are registered through cm_ll_data.
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Acked-by: Paul Walmsley <paul@pwsan.com>
Tested-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/cm.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm33xx.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm33xx.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm_common.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cminst44xx.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cminst44xx.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 10 |
7 files changed, 45 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 695c34dd37ca..3ecc5d73e2c5 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h | |||
@@ -45,18 +45,23 @@ extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); | |||
45 | * struct cm_ll_data - fn ptrs to per-SoC CM function implementations | 45 | * struct cm_ll_data - fn ptrs to per-SoC CM function implementations |
46 | * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl | 46 | * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl |
47 | * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl | 47 | * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl |
48 | * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl | ||
48 | */ | 49 | */ |
49 | struct cm_ll_data { | 50 | struct cm_ll_data { |
50 | int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, | 51 | int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, |
51 | u8 *idlest_reg_id); | 52 | u8 *idlest_reg_id); |
52 | int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg, | 53 | int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg, |
53 | u8 idlest_shift); | 54 | u8 idlest_shift); |
55 | int (*wait_module_idle)(u8 part, s16 prcm_mod, u16 idlest_reg, | ||
56 | u8 idlest_shift); | ||
54 | }; | 57 | }; |
55 | 58 | ||
56 | extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | 59 | extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, |
57 | u8 *idlest_reg_id); | 60 | u8 *idlest_reg_id); |
58 | int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, | 61 | int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, |
59 | u8 idlest_shift); | 62 | u8 idlest_shift); |
63 | int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg, | ||
64 | u8 idlest_shift); | ||
60 | extern int cm_register(struct cm_ll_data *cld); | 65 | extern int cm_register(struct cm_ll_data *cld); |
61 | extern int cm_unregister(struct cm_ll_data *cld); | 66 | extern int cm_unregister(struct cm_ll_data *cld); |
62 | 67 | ||
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index e022a8d57060..d57fa5fe9e51 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c | |||
@@ -250,14 +250,17 @@ static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, | |||
250 | /** | 250 | /** |
251 | * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' | 251 | * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' |
252 | * state | 252 | * state |
253 | * @part: CM partition, ignored for AM33xx | ||
253 | * @inst: CM instance register offset (*_INST macro) | 254 | * @inst: CM instance register offset (*_INST macro) |
254 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 255 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
256 | * @bit_shift: bit shift for the register, ignored for AM33xx | ||
255 | * | 257 | * |
256 | * Wait for the module IDLEST to be disabled. Some PRCM transition, | 258 | * Wait for the module IDLEST to be disabled. Some PRCM transition, |
257 | * like reset assertion or parent clock de-activation must wait the | 259 | * like reset assertion or parent clock de-activation must wait the |
258 | * module to be fully disabled. | 260 | * module to be fully disabled. |
259 | */ | 261 | */ |
260 | int am33xx_cm_wait_module_idle(u16 inst, u16 clkctrl_offs) | 262 | static int am33xx_cm_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, |
263 | u8 bit_shift) | ||
261 | { | 264 | { |
262 | int i = 0; | 265 | int i = 0; |
263 | 266 | ||
@@ -364,6 +367,7 @@ struct clkdm_ops am33xx_clkdm_operations = { | |||
364 | 367 | ||
365 | static struct cm_ll_data am33xx_cm_ll_data = { | 368 | static struct cm_ll_data am33xx_cm_ll_data = { |
366 | .wait_module_ready = &am33xx_cm_wait_module_ready, | 369 | .wait_module_ready = &am33xx_cm_wait_module_ready, |
370 | .wait_module_idle = &am33xx_cm_wait_module_idle, | ||
367 | }; | 371 | }; |
368 | 372 | ||
369 | int __init am33xx_cm_init(void) | 373 | int __init am33xx_cm_init(void) |
diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index fbbedf2c9bec..a0daea84fbe9 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h | |||
@@ -382,16 +382,11 @@ void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs); | |||
382 | int am33xx_cm_init(void); | 382 | int am33xx_cm_init(void); |
383 | 383 | ||
384 | #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) | 384 | #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) |
385 | int am33xx_cm_wait_module_idle(u16 inst, u16 clkctrl_offs); | ||
386 | extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, | 385 | extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, |
387 | u16 clkctrl_offs); | 386 | u16 clkctrl_offs); |
388 | extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, | 387 | extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, |
389 | u16 clkctrl_offs); | 388 | u16 clkctrl_offs); |
390 | #else | 389 | #else |
391 | static inline int am33xx_cm_wait_module_idle(u16 inst, u16 clkctrl_offs) | ||
392 | { | ||
393 | return 0; | ||
394 | } | ||
395 | static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, | 390 | static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, |
396 | u16 clkctrl_offs) | 391 | u16 clkctrl_offs) |
397 | { | 392 | { |
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index dd191837ac13..c6237df288d8 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c | |||
@@ -98,6 +98,32 @@ int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, | |||
98 | } | 98 | } |
99 | 99 | ||
100 | /** | 100 | /** |
101 | * omap_cm_wait_module_idle - wait for a module to enter idle or standby | ||
102 | * @part: PRCM partition | ||
103 | * @prcm_mod: PRCM module offset | ||
104 | * @idlest_reg: CM_IDLESTx register | ||
105 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | ||
106 | * | ||
107 | * Wait for the PRCM to indicate that the module identified by | ||
108 | * (@prcm_mod, @idlest_id, @idlest_shift) is no longer clocked. Return | ||
109 | * 0 upon success, -EBUSY if the module doesn't enable in time, or | ||
110 | * -EINVAL if no per-SoC wait_module_idle() function pointer has been | ||
111 | * registered or if the idlest register is unknown on the SoC. | ||
112 | */ | ||
113 | int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg, | ||
114 | u8 idlest_shift) | ||
115 | { | ||
116 | if (!cm_ll_data->wait_module_idle) { | ||
117 | WARN_ONCE(1, "cm: %s: no low-level function defined\n", | ||
118 | __func__); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
122 | return cm_ll_data->wait_module_idle(part, prcm_mod, idlest_reg, | ||
123 | idlest_shift); | ||
124 | } | ||
125 | |||
126 | /** | ||
101 | * cm_register - register per-SoC low-level data with the CM | 127 | * cm_register - register per-SoC low-level data with the CM |
102 | * @cld: low-level per-SoC OMAP CM data & function pointers to register | 128 | * @cld: low-level per-SoC OMAP CM data & function pointers to register |
103 | * | 129 | * |
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index c4f42de7f718..7ae1cc22eb5c 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c | |||
@@ -293,12 +293,14 @@ static int omap4_cminst_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, | |||
293 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 293 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
294 | * @inst: CM instance register offset (*_INST macro) | 294 | * @inst: CM instance register offset (*_INST macro) |
295 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 295 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
296 | * @bit_shift: Bit shift for the register, ignored for OMAP4+ | ||
296 | * | 297 | * |
297 | * Wait for the module IDLEST to be disabled. Some PRCM transition, | 298 | * Wait for the module IDLEST to be disabled. Some PRCM transition, |
298 | * like reset assertion or parent clock de-activation must wait the | 299 | * like reset assertion or parent clock de-activation must wait the |
299 | * module to be fully disabled. | 300 | * module to be fully disabled. |
300 | */ | 301 | */ |
301 | int omap4_cminst_wait_module_idle(u8 part, u16 inst, u16 clkctrl_offs) | 302 | static int omap4_cminst_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, |
303 | u8 bit_shift) | ||
302 | { | 304 | { |
303 | int i = 0; | 305 | int i = 0; |
304 | 306 | ||
@@ -510,6 +512,7 @@ struct clkdm_ops am43xx_clkdm_operations = { | |||
510 | 512 | ||
511 | static struct cm_ll_data omap4xxx_cm_ll_data = { | 513 | static struct cm_ll_data omap4xxx_cm_ll_data = { |
512 | .wait_module_ready = &omap4_cminst_wait_module_ready, | 514 | .wait_module_ready = &omap4_cminst_wait_module_ready, |
515 | .wait_module_idle = &omap4_cminst_wait_module_idle, | ||
513 | }; | 516 | }; |
514 | 517 | ||
515 | int __init omap4_cm_init(void) | 518 | int __init omap4_cm_init(void) |
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h index fad0a97c033b..9a223ddc9467 100644 --- a/arch/arm/mach-omap2/cminst44xx.h +++ b/arch/arm/mach-omap2/cminst44xx.h | |||
@@ -16,7 +16,6 @@ void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs); | |||
16 | void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); | 16 | void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); |
17 | void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); | 17 | void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); |
18 | void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); | 18 | void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); |
19 | int omap4_cminst_wait_module_idle(u8 part, u16 inst, u16 clkctrl_offs); | ||
20 | extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, | 19 | extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, |
21 | u16 clkctrl_offs); | 20 | u16 clkctrl_offs); |
22 | extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, | 21 | extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 1f7dd7dca7bb..03a42b37ef18 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1026,9 +1026,9 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh) | |||
1026 | if (oh->flags & HWMOD_NO_IDLEST) | 1026 | if (oh->flags & HWMOD_NO_IDLEST) |
1027 | return 0; | 1027 | return 0; |
1028 | 1028 | ||
1029 | return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, | 1029 | return omap_cm_wait_module_idle(oh->clkdm->prcm_partition, |
1030 | oh->clkdm->cm_inst, | 1030 | oh->clkdm->cm_inst, |
1031 | oh->prcm.omap4.clkctrl_offs); | 1031 | oh->prcm.omap4.clkctrl_offs, 0); |
1032 | } | 1032 | } |
1033 | 1033 | ||
1034 | /** | 1034 | /** |
@@ -1051,8 +1051,8 @@ static int _am33xx_wait_target_disable(struct omap_hwmod *oh) | |||
1051 | if (oh->flags & HWMOD_NO_IDLEST) | 1051 | if (oh->flags & HWMOD_NO_IDLEST) |
1052 | return 0; | 1052 | return 0; |
1053 | 1053 | ||
1054 | return am33xx_cm_wait_module_idle(oh->clkdm->cm_inst, | 1054 | return omap_cm_wait_module_idle(0, oh->clkdm->cm_inst, |
1055 | oh->prcm.omap4.clkctrl_offs); | 1055 | oh->prcm.omap4.clkctrl_offs, 0); |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | /** | 1058 | /** |