OMAP4: hwmod & CM: Implement the omap4_cm_wait_module_ready function
The return of the omap4_cm_wait_module_ready function is checked in order to avoid accessing the sysconfig register if the module is not in the correct state. In that case the _setup will exit without trying to reset using sysconfig. For the moment a warning is printed. A proper management of fclk and module reset will have to be done in order to init correctly the problematic IPs listed below. <4>omap_hwmod: ivahd: cannot be enabled (3) <4>omap_hwmod: iss: cannot be enabled (3) <4>omap_hwmod: tesla: cannot be enabled (3) <4>omap_hwmod: sdma: cannot be enabled (3) <4>omap_hwmod: sl2: cannot be enabled (3) <4>omap_hwmod: sad2d: cannot be enabled (3) <4>omap_hwmod: ducati: cannot be enabled (3) Signed-off-by: Benoit Cousson <b-cousson@ti.com> Signed-off-by: Paul Walmsley <paul@pwsan.com>
This commit is contained in:
committed by
Paul Walmsley
parent
d9e6625c70
commit
9a23dfe128
@@ -112,7 +112,7 @@ extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
|
|||||||
|
|
||||||
extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
|
extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
|
||||||
u8 idlest_shift);
|
u8 idlest_shift);
|
||||||
extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs);
|
extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
|
||||||
|
|
||||||
static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||||
{
|
{
|
||||||
|
@@ -21,19 +21,41 @@
|
|||||||
|
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
|
|
||||||
|
#include <plat/common.h>
|
||||||
|
|
||||||
#include "cm.h"
|
#include "cm.h"
|
||||||
#include "cm-regbits-44xx.h"
|
#include "cm-regbits-44xx.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby
|
* omap4_cm_wait_module_ready - wait for a module to be in 'func' state
|
||||||
* @prcm_mod: PRCM module offset (XXX example)
|
* @clkctrl_reg: CLKCTRL module address
|
||||||
* @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example)
|
|
||||||
*
|
*
|
||||||
* XXX document
|
* Wait for the module IDLEST to be functional. If the idle state is in any
|
||||||
|
* the non functional state (trans, idle or disabled), module and thus the
|
||||||
|
* sysconfig cannot be accessed and will probably lead to an "imprecise
|
||||||
|
* external abort"
|
||||||
|
*
|
||||||
|
* Module idle state:
|
||||||
|
* 0x0 func: Module is fully functional, including OCP
|
||||||
|
* 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
|
||||||
|
* abortion
|
||||||
|
* 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
|
||||||
|
* using separate functional clock
|
||||||
|
* 0x3 disabled: Module is disabled and cannot be accessed
|
||||||
|
*
|
||||||
|
* TODO: Need to handle module accessible in idle state
|
||||||
*/
|
*/
|
||||||
int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs)
|
int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
|
||||||
{
|
{
|
||||||
/* FIXME: Add clock manager related code */
|
int i = 0;
|
||||||
return 0;
|
|
||||||
|
if (!clkctrl_reg)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
omap_test_timeout(((__raw_readl(clkctrl_reg) &
|
||||||
|
OMAP4430_IDLEST_MASK) == 0),
|
||||||
|
MAX_MODULE_READY_TIME, i);
|
||||||
|
|
||||||
|
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -819,11 +819,8 @@ static int _wait_target_ready(struct omap_hwmod *oh)
|
|||||||
ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
|
ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
|
||||||
oh->prcm.omap2.idlest_reg_id,
|
oh->prcm.omap2.idlest_reg_id,
|
||||||
oh->prcm.omap2.idlest_idle_bit);
|
oh->prcm.omap2.idlest_idle_bit);
|
||||||
#if 0
|
|
||||||
} else if (cpu_is_omap44xx()) {
|
} else if (cpu_is_omap44xx()) {
|
||||||
ret = omap4_cm_wait_module_ready(oh->prcm.omap4.module_offs,
|
ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg);
|
||||||
oh->prcm.omap4.device_offs);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
BUG();
|
BUG();
|
||||||
};
|
};
|
||||||
@@ -912,16 +909,21 @@ static int _enable(struct omap_hwmod *oh)
|
|||||||
_add_initiator_dep(oh, mpu_oh);
|
_add_initiator_dep(oh, mpu_oh);
|
||||||
_enable_clocks(oh);
|
_enable_clocks(oh);
|
||||||
|
|
||||||
if (oh->class->sysc) {
|
|
||||||
if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
|
|
||||||
_update_sysc_cache(oh);
|
|
||||||
_sysc_enable(oh);
|
|
||||||
}
|
|
||||||
|
|
||||||
r = _wait_target_ready(oh);
|
r = _wait_target_ready(oh);
|
||||||
if (!r)
|
if (!r) {
|
||||||
oh->_state = _HWMOD_STATE_ENABLED;
|
oh->_state = _HWMOD_STATE_ENABLED;
|
||||||
|
|
||||||
|
/* Access the sysconfig only if the target is ready */
|
||||||
|
if (oh->class->sysc) {
|
||||||
|
if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
|
||||||
|
_update_sysc_cache(oh);
|
||||||
|
_sysc_enable(oh);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
|
||||||
|
oh->name, r);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -999,7 +1001,7 @@ static int _shutdown(struct omap_hwmod *oh)
|
|||||||
static int _setup(struct omap_hwmod *oh)
|
static int _setup(struct omap_hwmod *oh)
|
||||||
{
|
{
|
||||||
struct omap_hwmod_ocp_if *os;
|
struct omap_hwmod_ocp_if *os;
|
||||||
int i;
|
int i, r;
|
||||||
|
|
||||||
if (!oh)
|
if (!oh)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1023,7 +1025,12 @@ static int _setup(struct omap_hwmod *oh)
|
|||||||
|
|
||||||
oh->_state = _HWMOD_STATE_INITIALIZED;
|
oh->_state = _HWMOD_STATE_INITIALIZED;
|
||||||
|
|
||||||
_enable(oh);
|
r = _enable(oh);
|
||||||
|
if (r) {
|
||||||
|
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
|
||||||
|
oh->name, oh->_state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
|
if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user