[RFC 4/6] ARM: OMAP3: hwmod data: add custom setup_preprogram for iva hwmod
From: Tero Kristo <hidden>
Date: 2012-07-13 16:37:37
Also in:
linux-omap
Subsystem:
arm port, omap hwmod data, omap power management support, omap2+ support, the rest · Maintainers:
Russell King, Paul Walmsley, Kevin Hilman, Aaro Koskinen, Andreas Kemnade, Roger Quadros, Tony Lindgren, Linus Torvalds
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 <redacted>
---
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 --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__ */
--
1.7.4.1