Commit 35513171 authored by Rajendra Nayak's avatar Rajendra Nayak Committed by Paul Walmsley
Browse files

ARM: OMAP2+: hwmod: Fix sidle programming in _enable_sysc()/_idle_sysc()



_enable_sysc() and _idle_sysc() handle the midle mode programming correctly
and program HWMOD_IDLEMODE_SMART or HWMOD_IDLEMODE_SMART_WKUP respectively
for supported IPs (The ones which support hardware controlled midle modes)

However the same programming logic is missing when it comes to sidle mode
programming. Here they seem to just set HWMOD_IDLEMODE_SMART (Again for the
ones which support hardware controlled sidle modes)

This problem was hidden due to the fact that a call to _enable_wakeup()
in those same functions would overwrite the idlemodes and program them
correctly (to HWMOD_IDLEMODE_SMART_WKUP in the supported cases)

So fix the sidlemode handling correctly in these functions and handle the
_enable_wakeup() for SIDLEMODE supported IPs same as the way its handled
for MIDLEMODE supported ones.

Tested-by: default avatarVaibhav Bedia <vaibhav.bedia@ti.com>
Tested-by: default avatarSourav Poddar <sourav.poddar@ti.com>
Signed-off-by: default avatarRajendra Nayak <rnayak@ti.com>
Signed-off-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: default avatarKevin Hilman <khilman@linaro.org>
Tested-by: Kevin Hilman <khilman@linaro.org>  # OMAP4/Panda
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
parent f722406f
Loading
Loading
Loading
Loading
+25 −17
Original line number Diff line number Diff line
@@ -1356,13 +1356,26 @@ static void _enable_sysc(struct omap_hwmod *oh)

	clkdm = _get_clkdm(oh);
	if (sf & SYSC_HAS_SIDLEMODE) {
		if (oh->flags & HWMOD_SWSUP_SIDLE) {
			idlemode = HWMOD_IDLEMODE_NO;
		} else {
			if (sf & SYSC_HAS_ENAWAKEUP)
				_enable_wakeup(oh, &v);
			if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
				idlemode = HWMOD_IDLEMODE_SMART_WKUP;
			else
				idlemode = HWMOD_IDLEMODE_SMART;
		}

		/*
		 * This is special handling for some IPs like
		 * 32k sync timer. Force them to idle!
		 */
		clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
		if (clkdm_act && !(oh->class->sysc->idlemodes &
				   (SIDLE_SMART | SIDLE_SMART_WKUP)))
			idlemode = HWMOD_IDLEMODE_FORCE;
		else
			idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
				HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;

		_set_slave_idlemode(oh, idlemode, &v);
	}

@@ -1391,10 +1404,6 @@ static void _enable_sysc(struct omap_hwmod *oh)
	    (sf & SYSC_HAS_CLOCKACTIVITY))
		_set_clockactivity(oh, oh->class->sysc->clockact, &v);

	/* If slave is in SMARTIDLE, also enable wakeup */
	if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
		_enable_wakeup(oh, &v);

	_write_sysconfig(v, oh);

	/*
@@ -1430,13 +1439,16 @@ static void _idle_sysc(struct omap_hwmod *oh)
	sf = oh->class->sysc->sysc_flags;

	if (sf & SYSC_HAS_SIDLEMODE) {
		/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */
		if (oh->flags & HWMOD_SWSUP_SIDLE ||
		    !(oh->class->sysc->idlemodes &
		      (SIDLE_SMART | SIDLE_SMART_WKUP)))
		if (oh->flags & HWMOD_SWSUP_SIDLE) {
			idlemode = HWMOD_IDLEMODE_FORCE;
		} else {
			if (sf & SYSC_HAS_ENAWAKEUP)
				_enable_wakeup(oh, &v);
			if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
				idlemode = HWMOD_IDLEMODE_SMART_WKUP;
			else
				idlemode = HWMOD_IDLEMODE_SMART;
		}
		_set_slave_idlemode(oh, idlemode, &v);
	}

@@ -1455,10 +1467,6 @@ static void _idle_sysc(struct omap_hwmod *oh)
		_set_master_standbymode(oh, idlemode, &v);
	}

	/* If slave is in SMARTIDLE, also enable wakeup */
	if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
		_enable_wakeup(oh, &v);

	_write_sysconfig(v, oh);
}