aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2013-12-08 20:39:02 -0500
committerPaul Walmsley <paul@pwsan.com>2013-12-09 13:51:08 -0500
commit313a76ee11cda6700548afe68499ef174a240688 (patch)
tree9f3229756b91b02f155e055ac4ae82b62dcab324 /arch
parentb483a4a5a7117ac7d21397770d5adb458c157dbe (diff)
ARM: OMAP2+: hwmod: Fix SOFTRESET logic
In _ocp_softreset(), after _set_softreset() + write_sysconfig(), the hwmod's sysc_cache will always contain SOFTRESET bit set so all further writes to sysconfig using this cache will initiate a repeated SOFTRESET e.g. enable_sysc(). This is true for OMAP3 like platforms that have RESET_DONE status in the SYSSTATUS register and so the the SOFTRESET bit in SYSCONFIG is not automatically cleared. It is not a problem for OMAP4 like platforms that indicate RESET completion by clearing the SOFTRESET bit in the SYSCONFIG register. This repeated SOFTRESET is undesired and was the root cause of USB host issues on OMAP3 platforms when hwmod was allowed to do the SOFTRESET for the USB Host module. To fix this we clear the SOFTRESET bit and update the sysconfig register + sysc_cache using write_sysconfig(). Signed-off-by: Roger Quadros <rogerq@ti.com> Tested-by: Tomi Valkeinen <tomi.valkeinen@ti.com> # Panda, BeagleXM [paul@pwsan.com: renamed _clr_softreset() to _clear_softreset()] Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e3f0ecaf87dd..cacc0c7e8634 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -399,7 +399,7 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
399} 399}
400 400
401/** 401/**
402 * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v 402 * _set_softreset: set OCP_SYSCONFIG.SOFTRESET bit in @v
403 * @oh: struct omap_hwmod * 403 * @oh: struct omap_hwmod *
404 * @v: pointer to register contents to modify 404 * @v: pointer to register contents to modify
405 * 405 *
@@ -427,6 +427,36 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
427} 427}
428 428
429/** 429/**
430 * _clear_softreset: clear OCP_SYSCONFIG.SOFTRESET bit in @v
431 * @oh: struct omap_hwmod *
432 * @v: pointer to register contents to modify
433 *
434 * Clear the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon
435 * error or 0 upon success.
436 */
437static int _clear_softreset(struct omap_hwmod *oh, u32 *v)
438{
439 u32 softrst_mask;
440
441 if (!oh->class->sysc ||
442 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
443 return -EINVAL;
444
445 if (!oh->class->sysc->sysc_fields) {
446 WARN(1,
447 "omap_hwmod: %s: sysc_fields absent for sysconfig class\n",
448 oh->name);
449 return -EINVAL;
450 }
451
452 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
453
454 *v &= ~softrst_mask;
455
456 return 0;
457}
458
459/**
430 * _wait_softreset_complete - wait for an OCP softreset to complete 460 * _wait_softreset_complete - wait for an OCP softreset to complete
431 * @oh: struct omap_hwmod * to wait on 461 * @oh: struct omap_hwmod * to wait on
432 * 462 *
@@ -1911,6 +1941,12 @@ static int _ocp_softreset(struct omap_hwmod *oh)
1911 ret = _set_softreset(oh, &v); 1941 ret = _set_softreset(oh, &v);
1912 if (ret) 1942 if (ret)
1913 goto dis_opt_clks; 1943 goto dis_opt_clks;
1944
1945 _write_sysconfig(v, oh);
1946 ret = _clear_softreset(oh, &v);
1947 if (ret)
1948 goto dis_opt_clks;
1949
1914 _write_sysconfig(v, oh); 1950 _write_sysconfig(v, oh);
1915 1951
1916 if (oh->class->sysc->srst_udelay) 1952 if (oh->class->sysc->srst_udelay)
@@ -3169,6 +3205,11 @@ int omap_hwmod_softreset(struct omap_hwmod *oh)
3169 goto error; 3205 goto error;
3170 _write_sysconfig(v, oh); 3206 _write_sysconfig(v, oh);
3171 3207
3208 ret = _clear_softreset(oh, &v);
3209 if (ret)
3210 goto error;
3211 _write_sysconfig(v, oh);
3212
3172error: 3213error:
3173 return ret; 3214 return ret;
3174} 3215}