|
@@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * _wait_softreset_complete - wait for an OCP softreset to complete
|
|
|
|
+ * @oh: struct omap_hwmod * to wait on
|
|
|
|
+ *
|
|
|
|
+ * Wait until the IP block represented by @oh reports that its OCP
|
|
|
|
+ * softreset is complete. This can be triggered by software (see
|
|
|
|
+ * _ocp_softreset()) or by hardware upon returning from off-mode (one
|
|
|
|
+ * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
|
|
|
|
+ * microseconds. Returns the number of microseconds waited.
|
|
|
|
+ */
|
|
|
|
+static int _wait_softreset_complete(struct omap_hwmod *oh)
|
|
|
|
+{
|
|
|
|
+ struct omap_hwmod_class_sysconfig *sysc;
|
|
|
|
+ u32 softrst_mask;
|
|
|
|
+ int c = 0;
|
|
|
|
+
|
|
|
|
+ sysc = oh->class->sysc;
|
|
|
|
+
|
|
|
|
+ if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
|
|
|
|
+ omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
|
|
|
|
+ & SYSS_RESETDONE_MASK),
|
|
|
|
+ MAX_MODULE_SOFTRESET_WAIT, c);
|
|
|
|
+ else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
|
|
|
|
+ softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
|
|
|
|
+ omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
|
|
|
|
+ & softrst_mask),
|
|
|
|
+ MAX_MODULE_SOFTRESET_WAIT, c);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return c;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
|
|
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
|
|
* @oh: struct omap_hwmod *
|
|
* @oh: struct omap_hwmod *
|
|
@@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
|
if (!oh->class->sysc)
|
|
if (!oh->class->sysc)
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Wait until reset has completed, this is needed as the IP
|
|
|
|
+ * block is reset automatically by hardware in some cases
|
|
|
|
+ * (off-mode for example), and the drivers require the
|
|
|
|
+ * IP to be ready when they access it
|
|
|
|
+ */
|
|
|
|
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
|
|
|
|
+ _enable_optional_clocks(oh);
|
|
|
|
+ _wait_softreset_complete(oh);
|
|
|
|
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
|
|
|
|
+ _disable_optional_clocks(oh);
|
|
|
|
+
|
|
v = oh->_sysc_cache;
|
|
v = oh->_sysc_cache;
|
|
sf = oh->class->sysc->sysc_flags;
|
|
sf = oh->class->sysc->sysc_flags;
|
|
|
|
|
|
@@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
|
|
*/
|
|
*/
|
|
static int _ocp_softreset(struct omap_hwmod *oh)
|
|
static int _ocp_softreset(struct omap_hwmod *oh)
|
|
{
|
|
{
|
|
- u32 v, softrst_mask;
|
|
|
|
|
|
+ u32 v;
|
|
int c = 0;
|
|
int c = 0;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
@@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)
|
|
if (oh->class->sysc->srst_udelay)
|
|
if (oh->class->sysc->srst_udelay)
|
|
udelay(oh->class->sysc->srst_udelay);
|
|
udelay(oh->class->sysc->srst_udelay);
|
|
|
|
|
|
- if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
|
|
|
|
- omap_test_timeout((omap_hwmod_read(oh,
|
|
|
|
- oh->class->sysc->syss_offs)
|
|
|
|
- & SYSS_RESETDONE_MASK),
|
|
|
|
- MAX_MODULE_SOFTRESET_WAIT, c);
|
|
|
|
- else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
|
|
|
|
- softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
|
|
|
|
- omap_test_timeout(!(omap_hwmod_read(oh,
|
|
|
|
- oh->class->sysc->sysc_offs)
|
|
|
|
- & softrst_mask),
|
|
|
|
- MAX_MODULE_SOFTRESET_WAIT, c);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ c = _wait_softreset_complete(oh);
|
|
if (c == MAX_MODULE_SOFTRESET_WAIT)
|
|
if (c == MAX_MODULE_SOFTRESET_WAIT)
|
|
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
|
|
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
|
|
oh->name, MAX_MODULE_SOFTRESET_WAIT);
|
|
oh->name, MAX_MODULE_SOFTRESET_WAIT);
|
|
@@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
|
|
if (oh->_state != _HWMOD_STATE_INITIALIZED)
|
|
if (oh->_state != _HWMOD_STATE_INITIALIZED)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
+ if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
|
|
|
|
+ return -EPERM;
|
|
|
|
+
|
|
if (oh->rst_lines_cnt == 0) {
|
|
if (oh->rst_lines_cnt == 0) {
|
|
r = _enable(oh);
|
|
r = _enable(oh);
|
|
if (r) {
|
|
if (r) {
|