diff mbox

[RFC,4/6] ARM: OMAP3: hwmod data: add custom setup_preprogram for iva hwmod

Message ID 1342197459-7920-5-git-send-email-t-kristo@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tero Kristo July 13, 2012, 4:37 p.m. UTC
IVA2 module must be properly put to idle mode during boot, as it is
possible that it is enabled by bootloader, and this will prevent
core retention/off. Previously this was done by an init time hook
from pm34xx.c file, but this functionality is now moved within
hwmod setup_preprogram hook for iva hwmod.

This patch introduces following warning during boot:

     omap_hwmod: iva: failed to hardreset

This is generated by asserting the 'logic' hardreset for IVA2
hwmod. However, this warning is not fatal, and doesn't cause any
functional problems.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   13 +++++-
 arch/arm/mach-omap2/pm34xx.c               |   49 -------------------
 include/linux/platform_data/omap3-iva.h    |   73 ++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 50 deletions(-)
 create mode 100644 include/linux/platform_data/omap3-iva.h
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 98bc6f9..1ef6c90 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -14,6 +14,12 @@ 
  *
  * XXX these should be marked initdata for multi-OMAP kernels
  */
+
+#include <linux/io.h>
+#include "control.h"
+#include "iomap.h"
+#include <linux/platform_data/omap3-iva.h>
+
 #include <plat/omap_hwmod.h>
 #include <mach/irqs.h>
 #include <plat/cpu.h>
@@ -105,9 +111,14 @@  static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = {
 	{ .name = "seq1", .rst_shift = 2, .st_shift = 10 },
 };
 
+static struct omap_hwmod_class omap3xxx_iva_hwmod_class = {
+	.name			= "iva",
+	.setup_preprogram	= hwmod_iva_preprogram,
+};
+
 static struct omap_hwmod omap3xxx_iva_hwmod = {
 	.name		= "iva",
-	.class		= &iva_hwmod_class,
+	.class		= &omap3xxx_iva_hwmod_class,
 	.clkdm_name	= "iva2_clkdm",
 	.rst_lines	= omap3xxx_iva_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap3xxx_iva_resets),
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 474ed9d..d407b32 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -333,54 +333,6 @@  restore:
 
 #endif /* CONFIG_SUSPEND */
 
-
-/**
- * omap3_iva_idle(): ensure IVA is in idle so it can be put into
- *                   retention
- *
- * In cases where IVA2 is activated by bootcode, it may prevent
- * full-chip retention or off-mode because it is not idle.  This
- * function forces the IVA2 into idle state so it can go
- * into retention/off and thus allow full-chip retention/off.
- *
- **/
-static void __init omap3_iva_idle(void)
-{
-	/* ensure IVA2 clock is disabled */
-	omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
-
-	/* if no clock activity, nothing else to do */
-	if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
-	      OMAP3430_CLKACTIVITY_IVA2_MASK))
-		return;
-
-	/* Reset IVA2 */
-	omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
-			  OMAP3430_RST2_IVA2_MASK |
-			  OMAP3430_RST3_IVA2_MASK,
-			  OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-
-	/* Enable IVA2 clock */
-	omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
-			 OMAP3430_IVA2_MOD, CM_FCLKEN);
-
-	/* Set IVA2 boot mode to 'idle' */
-	omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
-			 OMAP343X_CONTROL_IVA2_BOOTMOD);
-
-	/* Un-reset IVA2 */
-	omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-
-	/* Disable IVA2 clock */
-	omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
-
-	/* Reset IVA2 */
-	omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
-			  OMAP3430_RST2_IVA2_MASK |
-			  OMAP3430_RST3_IVA2_MASK,
-			  OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-}
-
 static void __init omap3_d2d_idle(void)
 {
 	u16 mask, padconf;
@@ -478,7 +430,6 @@  static void __init prcm_setup_regs(void)
 	/* Clear any pending PRCM interrupts */
 	omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-	omap3_iva_idle();
 	omap3_d2d_idle();
 }
 
diff --git a/include/linux/platform_data/omap3-iva.h b/include/linux/platform_data/omap3-iva.h
new file mode 100644
index 0000000..742349a
--- /dev/null
+++ b/include/linux/platform_data/omap3-iva.h
@@ -0,0 +1,73 @@ 
+/*
+ * OMAP3 IVA IP block integration
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Tero Kristo
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef __LINUX_PLATFORM_DATA_OMAP3_IVA_H__
+#define __LINUX_PLATFORM_DATA_OMAP3_IVA_H__
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include <plat/omap_hwmod.h>
+
+/**
+ * hwmod_iva_preprogram - execute reset sequence for IVA2
+ * @oh: pointer to iva2 hwmod
+ *
+ * Runs reset sequence for IVA2. In cases where IVA2 is activated
+ * by bootcode, it may prevent full-chip retention or off-mode
+ * because it is not idle. This function forces the IVA2 into idle
+ * state so it can go into retention/off and thus allow full-chip
+ * retention/off. Always returns 0.
+ */
+static int __maybe_unused hwmod_iva_preprogram(struct omap_hwmod *oh)
+{
+	int i;
+
+	/* Ensure clock is disabled */
+	omap_hwmod_enable_clocks(oh);
+	omap_hwmod_disable_clocks(oh);
+
+	/* Reset IVA2 */
+	for (i = 0; i < oh->rst_lines_cnt; i++)
+		omap_hwmod_assert_hardreset(oh, oh->rst_lines[i].name);
+
+
+	/* Enable IVA2 clock */
+	omap_hwmod_enable_clocks(oh);
+
+	/* Set IVA2 bootmode to 'idle' */
+	omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
+			 OMAP343X_CONTROL_IVA2_BOOTMOD);
+
+	/* Un-reset IVA2 */
+	for (i = 0; i < oh->rst_lines_cnt; i++)
+		omap_hwmod_deassert_hardreset(oh, oh->rst_lines[i].name);
+
+	/* Disable IVA2 clock */
+	omap_hwmod_disable_clocks(oh);
+
+	/* Reset IVA2 */
+	for (i = 0; i < oh->rst_lines_cnt; i++)
+		omap_hwmod_assert_hardreset(oh, oh->rst_lines[i].name);
+
+	return 0;
+}
+
+#endif /* __LINUX_PLATFORM_DATA_OMAP3_IVA_H__ */