All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHV2] OMAP3 PM: Fix for DSP Crash at OPP 1 and 2 under DVFS+SR operation
@ 2010-03-11 13:16 Vishwanath BS
  2010-03-17 18:01 ` Kevin Hilman
  2010-03-30  9:29 ` Paul Walmsley
  0 siblings, 2 replies; 6+ messages in thread
From: Vishwanath BS @ 2010-03-11 13:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Vishwanath BS, Shweta Gulati

From: Shweta Gulati <shweta.gulati@ti.com>

DSP usage at VDD1 OPP1 and OPP2 with Smartreflex enabled and any MM UCs
running DSP codec was earlier restricted as DSP crashed.
The root cause is wrong DPLL1/DPLL2 Bypass clock at VDD1 OPP1 and OPP2.
The solution is to make sure DPLL1/DPLL2 bypass clock is always less than 
maximum supported frequency for the specific OPP

Tested on 3630 ZOOM3.

changes in V2 : Rebased to new OPP implementation

Signed-off-by: Shweta Gulati <shweta.gulati@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
---
 arch/arm/mach-omap2/cm-regbits-34xx.h |    4 ++--
 arch/arm/mach-omap2/pm34xx.c          |   23 +++++++++++++++++++++++
 arch/arm/mach-omap2/resource34xx.c    |   28 +++++++++++++++++++++++++++-
 3 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index a3a3ca0..ee420ab 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -81,7 +81,7 @@
 
 /* CM_CLKSEL1_PLL_IVA2 */
 #define OMAP3430_IVA2_CLK_SRC_SHIFT			19
-#define OMAP3430_IVA2_CLK_SRC_MASK			(0x3 << 19)
+#define OMAP3430_IVA2_CLK_SRC_MASK			(0x7 << 19)
 #define OMAP3430_IVA2_DPLL_MULT_SHIFT			8
 #define OMAP3430_IVA2_DPLL_MULT_MASK			(0x7ff << 8)
 #define OMAP3430_IVA2_DPLL_DIV_SHIFT			0
@@ -126,7 +126,7 @@
 
 /* CM_CLKSEL1_PLL_MPU */
 #define OMAP3430_MPU_CLK_SRC_SHIFT			19
-#define OMAP3430_MPU_CLK_SRC_MASK			(0x3 << 19)
+#define OMAP3430_MPU_CLK_SRC_MASK			(0x7 << 19)
 #define OMAP3430_MPU_DPLL_MULT_SHIFT			8
 #define OMAP3430_MPU_DPLL_MULT_MASK			(0x7ff << 8)
 #define OMAP3430_MPU_DPLL_DIV_SHIFT			0
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b51b461..494e5e6
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -828,6 +828,29 @@ static void __init omap3_d2d_idle(void)
 
 static void __init prcm_setup_regs(void)
 {
+	u32 cm_clksel1_mpu, cm_clksel1_iva2;
+
+	/*set Bypass clock dividers for MPU and IVA */
+	cm_clksel1_mpu = cm_read_mod_reg(MPU_MOD, CM_CLKSEL1);
+	cm_clksel1_iva2 = cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+	if (cpu_is_omap3630()) {
+		cm_clksel1_iva2 = (cm_clksel1_iva2 &
+					~(OMAP3430_IVA2_CLK_SRC_MASK)) |
+					(0x2 << OMAP3430_IVA2_CLK_SRC_SHIFT);
+		cm_clksel1_mpu = (cm_clksel1_mpu &
+					~(OMAP3430_MPU_CLK_SRC_MASK)) |
+					(0x1 << OMAP3430_MPU_CLK_SRC_SHIFT);
+	} else if (cpu_is_omap34xx()) {
+		cm_clksel1_iva2 = (cm_clksel1_iva2 &
+					~(OMAP3430_IVA2_CLK_SRC_MASK)) |
+					(0x4 << OMAP3430_IVA2_CLK_SRC_SHIFT);
+		cm_clksel1_mpu = (cm_clksel1_mpu &
+					~(OMAP3430_MPU_CLK_SRC_MASK)) |
+					(0x2 << OMAP3430_MPU_CLK_SRC_SHIFT);
+		}
+	cm_write_mod_reg(cm_clksel1_iva2, OMAP3430_IVA2_MOD, CM_CLKSEL1);
+	cm_write_mod_reg(cm_clksel1_mpu, MPU_MOD, CM_CLKSEL1);
+
 	/* XXX Reset all wkdeps. This should be done when initializing
 	 * powerdomains */
 	prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index c6cce8b..03d7fce
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -276,12 +276,13 @@ static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
 
 static int program_opp_freq(int res, int target_level, int current_level)
 {
-	int ret = 0, l3_div;
+	int ret = 0, l3_div, mpu_div, iva2_div;
 	int *curr_opp;
 	unsigned long mpu_freq, dsp_freq, l3_freq;
 #ifndef CONFIG_CPU_FREQ
 	unsigned long mpu_cur_freq;
 #endif
+	u32 cm_clksel1_mpu, cm_clksel1_iva2, max_core_clk;
 
 	/* Check if I can actually switch or not */
 	if (res == VDD1_OPP) {
@@ -299,6 +300,31 @@ static int program_opp_freq(int res, int target_level, int current_level)
 
 	lock_scratchpad_sem();
 	if (res == VDD1_OPP) {
+		/* adjust bypass clock diviers */
+		max_core_clk = ULONG_MAX;
+		opp_find_freq_floor(OPP_L3, &max_core_clk);
+		l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+				OMAP3430_CLKSEL_L3_MASK;
+
+		max_core_clk *= l3_div;
+		mpu_div = 1 << (max_core_clk / mpu_freq);
+		iva2_div = 1 << (max_core_clk / dsp_freq);
+
+		cm_clksel1_mpu = cm_read_mod_reg(MPU_MOD, CM_CLKSEL1);
+		cm_clksel1_iva2 =
+				cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+
+		cm_clksel1_iva2 = (cm_clksel1_iva2 &
+				~(OMAP3430_IVA2_CLK_SRC_MASK)) |
+				(iva2_div << OMAP3430_IVA2_CLK_SRC_SHIFT);
+		cm_clksel1_mpu = (cm_clksel1_mpu &
+				~(OMAP3430_MPU_CLK_SRC_MASK)) |
+				(mpu_div << OMAP3430_MPU_CLK_SRC_SHIFT);
+
+		cm_write_mod_reg(cm_clksel1_iva2,
+				OMAP3430_IVA2_MOD, CM_CLKSEL1);
+		cm_write_mod_reg(cm_clksel1_mpu, MPU_MOD, CM_CLKSEL1);
+
 		curr_opp = &curr_vdd1_opp;
 		clk_set_rate(dpll1_clk, mpu_freq);
 		clk_set_rate(dpll2_clk, dsp_freq);
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-03-30  9:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-11 13:16 [PATCHV2] OMAP3 PM: Fix for DSP Crash at OPP 1 and 2 under DVFS+SR operation Vishwanath BS
2010-03-17 18:01 ` Kevin Hilman
2010-03-29  5:09   ` Sripathy, Vishwanath
2010-03-30  9:31     ` Paul Walmsley
2010-03-30  9:45       ` Sripathy, Vishwanath
2010-03-30  9:29 ` Paul Walmsley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.