aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorFernando Guzman Lugo <fernando.lugo@ti.com>2011-08-09 13:31:19 -0500
committerIliyan Malchev <malchev@google.com>2011-08-29 19:55:48 -0700
commitdc535126ab760cfdc58c076bc3adee5e9b390502 (patch)
tree19c475643ac9321799e899edbaff02c72de3ec0f /arch/arm
parentda82940deff70bd2227b0c072e55cac01db2f2b7 (diff)
downloadkernel_samsung_espresso10-dc535126ab760cfdc58c076bc3adee5e9b390502.zip
kernel_samsung_espresso10-dc535126ab760cfdc58c076bc3adee5e9b390502.tar.gz
kernel_samsung_espresso10-dc535126ab760cfdc58c076bc3adee5e9b390502.tar.bz2
omap: hwmod: add softreset delay field
Due to HW limitation, some IPs should not be accessed just after a softreset. Since the current hwmod sequence is accessing the sysconfig register just after the reset, it might lead to OCP bus error in that case. Add a new field in the sysconfig structure to specify a delay in usecs needed after doing a softreset. In the case of the ISS and FDIF modules, the L3 OCP port will be disconnected upon a SW reset. That issue was confirmed with HW simulation and an errata should be available soon. The HW recommendation to avoid that is to wait for 100 OCP clk cycles, before accessing the IP. Considering the worse case (OPP50), the L3 bus will run at 100 MHz, so a 1 usec delay is needed. Add an x2 margin to be safe. Change-Id: Ieed02fee00c555d93de83080b11fd8c911904591 Acked-by: Benoit Cousson <b-cousson@ti.com> Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c18
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h2
3 files changed, 23 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6b23e13..2b29cef 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1181,6 +1181,9 @@ static int _ocp_softreset(struct omap_hwmod *oh)
goto dis_opt_clks;
_write_sysconfig(v, oh);
+ if (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)
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 5562def..b52857d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2325,6 +2325,15 @@ static struct omap_hwmod omap44xx_emif2_hwmod = {
static struct omap_hwmod_class_sysconfig omap44xx_fdif_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
+ /*
+ * FDIF needs 100 OCP clk cycles delay after a softreset before
+ * accessing sysconfig again.
+ * The lowest frequency at the moment for L3 bus is 100 MHz, so
+ * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+ *
+ * TODO: Indicate errata when available.
+ */
+ .srst_udelay = 2,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -3250,6 +3259,15 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
+ /*
+ * ISS needs 100 OCP clk cycles delay after a softreset before
+ * accessing sysconfig again.
+ * The lowest frequency at the moment for L3 bus is 100 MHz, so
+ * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+ *
+ * TODO: Indicate errata when available.
+ */
+ .srst_udelay = 2,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index cb5799d..d99b953 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -300,6 +300,7 @@ struct omap_hwmod_sysc_fields {
* @rev_offs: IP block revision register offset (from module base addr)
* @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
* @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @srst_udelay: Delay needed after doing a softreset in usecs
* @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
* @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
* @clockact: the default value of the module CLOCKACTIVITY bits
@@ -325,6 +326,7 @@ struct omap_hwmod_class_sysconfig {
u16 sysc_offs;
u16 syss_offs;
u16 sysc_flags;
+ u16 srst_udelay;
u8 idlemodes;
u8 clockact;
struct omap_hwmod_sysc_fields *sysc_fields;