* [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-25 9:50 ` Felipe Balbi
2008-06-25 9:13 ` [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
` (6 subsequent siblings)
7 siblings, 1 reply; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap
Current omap hsmmc driver is not pm friendly. Build it as a module
because it prevents omap3 retention.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/configs/omap_3430sdp_defconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig
index 947c25f..5672a6e 100644
--- a/arch/arm/configs/omap_3430sdp_defconfig
+++ b/arch/arm/configs/omap_3430sdp_defconfig
@@ -1058,7 +1058,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD Host Controller Drivers
#
-CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_OMAP_HS=m
# CONFIG_MMC_SPI is not set
# CONFIG_NEW_LEDS is not set
CONFIG_RTC_LIB=y
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 9:13 ` [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module Jouni Hogander
@ 2008-06-25 9:50 ` Felipe Balbi
2008-06-25 11:17 ` Gadiyar, Anand
0 siblings, 1 reply; 27+ messages in thread
From: Felipe Balbi @ 2008-06-25 9:50 UTC (permalink / raw)
To: Jouni Hogander; +Cc: linux-omap
On Wed, 25 Jun 2008 12:13:40 +0300, Jouni Hogander
<jouni.hogander@nokia.com> wrote:
> Current omap hsmmc driver is not pm friendly. Build it as a module
> because it prevents omap3 retention.
Small comment.
At least this patch shouldn't be reverted, there's no reason
for not building drivers as modules. I'll do the same
to musb.
--
Best Regards,
Felipe Balbi
http://felipebalbi.com
me@felipebalbi.com
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 9:50 ` Felipe Balbi
@ 2008-06-25 11:17 ` Gadiyar, Anand
2008-06-25 12:03 ` Felipe Balbi
0 siblings, 1 reply; 27+ messages in thread
From: Gadiyar, Anand @ 2008-06-25 11:17 UTC (permalink / raw)
To: Felipe Balbi, Jouni Hogander; +Cc: linux-omap@vger.kernel.org
> > Current omap hsmmc driver is not pm friendly. Build it as a module
> > because it prevents omap3 retention.
>
> Small comment.
>
> At least this patch shouldn't be reverted, there's no reason
> for not building drivers as modules. I'll do the same
> to musb.
Actually there is. It really depends on what you want to do with the system.
For instance, the case where you are running a tight embedded system with a ramdisk filesystem - the modules would have to sit on the filesystem and would occupy precious space there. You might be better off having everything built into the kernel.
That being said, in my opinion it should be possible to have everything as modules with little difference in functionality. In this case if the OMAP HSMMC driver is not PM-friendly, then that should be fixed. Making it build as a module is at best a __temporary__ solution as Jouni points out.
The choice of building drivers into the kernel or as modules should be left to whoever builds the kernel. The defconfigs make life easy during testing but otherwise there is little reason to change them.
My $0.02,
Anand
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 11:17 ` Gadiyar, Anand
@ 2008-06-25 12:03 ` Felipe Balbi
2008-06-25 12:11 ` Igor Stoppa
0 siblings, 1 reply; 27+ messages in thread
From: Felipe Balbi @ 2008-06-25 12:03 UTC (permalink / raw)
To: Gadiyar, Anand; +Cc: Jouni Hogander, linux-omap
Hi,
On Wed, 25 Jun 2008 16:47:30 +0530, "Gadiyar, Anand" <gadiyar@ti.com>
wrote:
> Actually there is. It really depends on what you want to do with the
> system.
>
> For instance, the case where you are running a tight embedded system with
> a ramdisk filesystem - the modules would have to sit on the filesystem
and
> would occupy precious space there. You might be better off having
> everything built into the kernel.
>
> That being said, in my opinion it should be possible to have everything
as
> modules with little difference in functionality. In this case if the OMAP
> HSMMC driver is not PM-friendly, then that should be fixed. Making it
build
> as a module is at best a __temporary__ solution as Jouni points out.
>
> The choice of building drivers into the kernel or as modules should be
> left to whoever builds the kernel. The defconfigs make life easy during
> testing but otherwise there is little reason to change them.
That's true but 3430sdp is far from a tight embedded system. It's a full
fledged omap3430-based board with plenty of memory space for everything
we need.
On the other hand, building as module allow us to just unload the module
if it's causing problems like preventing retetion. Besides, at least in
case on the SDPs, most of the people will use nfs anyways, which makes
a lot easier to upload the new modules to the board allowing us to test
new features in a module without even rebooting the board, just by
rmmod/insmod.
Again, I agree with that with a tight embedded system, it's better to
have everything into the kernel, but then again, we have to believe
that every single piece of sw is working exactly the way it should,
which is not always true during the development process of our drivers.
At least hsmmc and musb drivers still have some stuff to be taken
care of. Having them as modules, would allow faster development
cycle with less reboots on the target board.
And like you said, if the defconfig is all modular (or all built-in)
the user/manufacturer/hacker can always change it later. Although
I defend that Reference Boards' defconfigs should be as modular
as possible.
My 2 cents ;-)
--
Best Regards,
Felipe Balbi
http://blog.felipebalbi.com
me@felipebalbi.com
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 12:03 ` Felipe Balbi
@ 2008-06-25 12:11 ` Igor Stoppa
2008-06-25 12:40 ` Gadiyar, Anand
0 siblings, 1 reply; 27+ messages in thread
From: Igor Stoppa @ 2008-06-25 12:11 UTC (permalink / raw)
To: ext Felipe Balbi; +Cc: Gadiyar, Anand, Jouni Hogander, linux-omap
On Wed, 2008-06-25 at 07:03 -0500, ext Felipe Balbi wrote:
> And like you said, if the defconfig is all modular (or all built-in)
> the user/manufacturer/hacker can always change it later. Although
> I defend that Reference Boards' defconfigs should be as modular
> as possible.
I totally agree: furthermore testing power features is damn easier if we
can bisect the modules and zero on the offending driver.
And on top of that, having modules allows to makes it simpler to address
in one go different boards and subarchitectures.
The SDP is to many of us just the mean to develop sw for the real HW.
Modules don't harm SDP only users but help those involved in product
creation.
--
Cheers, Igor
---
Igor Stoppa
Maemo Software - Nokia Devices R&D - Helsinki
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 12:11 ` Igor Stoppa
@ 2008-06-25 12:40 ` Gadiyar, Anand
2008-06-25 13:23 ` Igor Stoppa
0 siblings, 1 reply; 27+ messages in thread
From: Gadiyar, Anand @ 2008-06-25 12:40 UTC (permalink / raw)
To: igor.stoppa@nokia.com, ext Felipe Balbi
Cc: Jouni Hogander, linux-omap@vger.kernel.org
> > And like you said, if the defconfig is all modular (or all built-in)
> > the user/manufacturer/hacker can always change it later. Although
> > I defend that Reference Boards' defconfigs should be as modular
> > as possible.
>
> I totally agree: furthermore testing power features is damn easier if we
> can bisect the modules and zero on the offending driver.
I agree too. No contest.
On the other hand, the easiest way to find that something is broken is if
it is built-in in the kernel. Else, you could easily overlook some module
that you never loaded because it wasn't an area you worked on. For a recent
example of this, it is not very likely that I would have found that the
display driver was broken because if it were a module, I would rarely load
it. I caught it only because it was preventing a defconfig kernel from booting.
We do have an "allmodconfig" target. How about using that when you want to
bisect and find the broken driver?
My main bone of contention was the statement that there was no reason for
not building something as a module. There is a case for building drivers
into the kernel. Whether it is the best choice is something that depends
on what one is trying to achieve.
>
> And on top of that, having modules allows to makes it simpler to address
> in one go different boards and subarchitectures.
I'm afraid I don't understand. How would having a driver as a module or
built-in make a difference when targetting different boards?
- Anand
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 12:40 ` Gadiyar, Anand
@ 2008-06-25 13:23 ` Igor Stoppa
2008-06-26 4:25 ` Gadiyar, Anand
0 siblings, 1 reply; 27+ messages in thread
From: Igor Stoppa @ 2008-06-25 13:23 UTC (permalink / raw)
To: ext Gadiyar, Anand
Cc: ext Felipe Balbi, Jouni Hogander, linux-omap@vger.kernel.org
Hi,
On Wed, 2008-06-25 at 18:10 +0530, ext Gadiyar, Anand wrote:
> My main bone of contention was the statement that there was no reason for
> not building something as a module. There is a case for building drivers
> into the kernel. Whether it is the best choice is something that depends
> on what one is trying to achieve.
As Felipe wrote, it is easy to reconfigure a module to be build in than
it is to get a build in and have it to be compilable and usable as
module. Developing a module gives you for free the builtin case.
The other way is not always true.
Your case of "let's veryfy all the modules at once by converting them to
built-ins" is more the exception than the rule.
> > And on top of that, having modules allows to makes it simpler to address
> > in one go different boards and subarchitectures.
>
> I'm afraid I don't understand. How would having a driver as a module or
> built-in make a difference when targetting different boards?
I can do just one build and use the same binary to do the deployment to
different boards.
That's the direction the kernel is currently going to, with code that
probes for OMAP version and uses the appropriate register addresses.
The bootloader can pass the board type as option.
--
Cheers, Igor
---
Igor Stoppa
Maemo Software - Nokia Devices R&D - Helsinki
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-25 13:23 ` Igor Stoppa
@ 2008-06-26 4:25 ` Gadiyar, Anand
2008-06-26 7:28 ` Felipe Balbi
0 siblings, 1 reply; 27+ messages in thread
From: Gadiyar, Anand @ 2008-06-26 4:25 UTC (permalink / raw)
To: igor.stoppa@nokia.com
Cc: ext Felipe Balbi, Jouni Hogander, linux-omap@vger.kernel.org
> > My main bone of contention was the statement that there was no reason for
> > not building something as a module. There is a case for building drivers
> > into the kernel. Whether it is the best choice is something that depends
> > on what one is trying to achieve.
>
> As Felipe wrote, it is easy to reconfigure a module to be build in than
> it is to get a build in and have it to be compilable and usable as
> module. Developing a module gives you for free the builtin case.
> The other way is not always true.
Agreed. That is correct.
> Your case of "let's veryfy all the modules at once by converting them to
> built-ins" is more the exception than the rule.
That wasn't what I said or meant. What I did want to bring out was that having
something built-in might give it more exposure to test by someone who wasn't
actively working on that area. And most bugs are caught by people other than
the active developers.
> > > And on top of that, having modules allows to makes it simpler to address
> > > in one go different boards and subarchitectures.
> >
> > I'm afraid I don't understand. How would having a driver as a module or
> > built-in make a difference when targetting different boards?
>
> I can do just one build and use the same binary to do the deployment to
> different boards.
This can still be done if you have everything built-in. Is there any reason for
such a all-built-in kernel not to work across boards?
At first glance to your email, I thought you had a valid point here. Thinking a
little more, I think your point is valid only if you had a module that should not
be loaded on a particular board. In such a case, you would anyway want to fix that
module.
> That's the direction the kernel is currently going to, with code that
> probes for OMAP version and uses the appropriate register addresses.
>
> The bootloader can pass the board type as option.
This can be done with a modular kernel as well as with an all-built-in kernel.
Yes, having a modular kernel is useful. And it is probably the way to go. But please
don't tell me that you can't do the same things with almost everything built-in.
The 2430 defconfig has almost everything modular, while the 3430 defconfig doesn't.
I propose we start a separate defconfig for the modular case or use allmodconfig.
Maybe even have this as the defconfig for the multi-omap kernel. If we keep the
individual defconfigs as a nearly all-built-in case, we can still get the best of
both worlds.
- Anand
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-26 4:25 ` Gadiyar, Anand
@ 2008-06-26 7:28 ` Felipe Balbi
2008-06-26 8:31 ` Gadiyar, Anand
0 siblings, 1 reply; 27+ messages in thread
From: Felipe Balbi @ 2008-06-26 7:28 UTC (permalink / raw)
To: Gadiyar, Anand; +Cc: igor.stoppa, Jouni Hogander, linux-omap
Hi,
On Thu, 26 Jun 2008 09:55:43 +0530, "Gadiyar, Anand" <gadiyar@ti.com>
wrote:
> That wasn't what I said or meant. What I did want to bring out was that
> having
> something built-in might give it more exposure to test by someone who
> wasn't
> actively working on that area. And most bugs are caught by people other
> than
> the active developers.
Not really, another usecase for modular kernel is that we don't wanna
add e.g. tea (radio) driver for n810 cuz it doesn't have that chip.
With modular kernel with proper MODULE_ALIAS() and udev, you just
flash the same kernel and modules in both n800 and n810 and tea driver
would only be probed in n800.
I think this is what Igor meant when we said about validation across
boards.
>
>
> At first glance to your email, I thought you had a valid point here.
> Thinking a
> little more, I think your point is valid only if you had a module that
> should not
> be loaded on a particular board. In such a case, you would anyway want to
> fix that
> module.
Or you rely on udev rules and keep the main kernel code smaller.
> Yes, having a modular kernel is useful. And it is probably the way to go.
> But please
> don't tell me that you can't do the same things with almost everything
> built-in.
some stuff you really can't. If your mmc driver get stuck somewhere, you
can't modprobe -r -f omap_hsmmc and restart your work with a built-in
mmc driver. With modular kernel, we really can do it: forcefully remove
the driver and reset the controller, this would give us oportunity to
analyze logs and try again by reloading the module.
With a built-in kernel, the only way out is reboot.
> The 2430 defconfig has almost everything modular, while the 3430
defconfig
> doesn't.
> I propose we start a separate defconfig for the modular case or use
> allmodconfig.
> Maybe even have this as the defconfig for the multi-omap kernel. If we
> keep the
> individual defconfigs as a nearly all-built-in case, we can still get the
> best of
> both worlds.
The thins is that normaly you'd have udev running anyways, and it would
automatically load modules based on /sys and correct MODULE_ALIAS()
and that's already another thing to test that can't be tested with built-in
modules.
We know that several omap drivers are missing MODULE_ALIAS() and recently
I've
added it to all twl4030 drivers for that purpose.
We can now rely that udev will correctly load the necessary module when we
need it. And when I stated that there's no reason for not building
everything as dynamic module for omaps, I was considering that we have
enough memory in our boards and generaly developers will use NFS
root file system anyways.
I think this discussion is now way too long for something really
simple: For development purposes on SDPs, dynamic linked modules
can increase the development cycle by decreasing the amount of
build/flash/reboot cycles.
--
Best Regards,
Felipe Balbi
http://blog.felipebalbi.com
me@felipebalbi.com
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-26 7:28 ` Felipe Balbi
@ 2008-06-26 8:31 ` Gadiyar, Anand
2008-06-26 13:20 ` Tony Lindgren
0 siblings, 1 reply; 27+ messages in thread
From: Gadiyar, Anand @ 2008-06-26 8:31 UTC (permalink / raw)
To: Felipe Balbi
Cc: igor.stoppa@nokia.com, Jouni Hogander, linux-omap@vger.kernel.org
> > That wasn't what I said or meant. What I did want to bring out was that having
> > something built-in might give it more exposure to test by someone who wasn't
> > actively working on that area. And most bugs are caught by people other than
> > the active developers.
>
> Not really, another usecase for modular kernel is that we don't wanna
> add e.g. tea (radio) driver for n810 cuz it doesn't have that chip.
> With modular kernel with proper MODULE_ALIAS() and udev, you just
> flash the same kernel and modules in both n800 and n810 and tea driver
> would only be probed in n800.
>
> I think this is what Igor meant when we said about validation across
> boards.
Ok. Fair enough. Point taken.
> > At first glance to your email, I thought you had a valid point here. Thinking a
> > little more, I think your point is valid only if you had a module that should not
> > be loaded on a particular board. In such a case, you would anyway want to fix that
> > module.
>
> Or you rely on udev rules and keep the main kernel code smaller.
>
> > Yes, having a modular kernel is useful. And it is probably the way to go. But please
> > don't tell me that you can't do the same things with almost everything built-in.
>
> some stuff you really can't. If your mmc driver get stuck somewhere, you
> can't modprobe -r -f omap_hsmmc and restart your work with a built-in
> mmc driver. With modular kernel, we really can do it: forcefully remove
> the driver and reset the controller, this would give us oportunity to
> analyze logs and try again by reloading the module.
>
> With a built-in kernel, the only way out is reboot.
Agreed.
> > The 2430 defconfig has almost everything modular, while the 3430 defconfig doesn't.
> > I propose we start a separate defconfig for the modular case or use allmodconfig.
> > Maybe even have this as the defconfig for the multi-omap kernel. If we keep the
> > individual defconfigs as a nearly all-built-in case, we can still get the best of
> > both worlds.
>
> The thins is that normaly you'd have udev running anyways, and it would
> automatically load modules based on /sys and correct MODULE_ALIAS()
> and that's already another thing to test that can't be tested with built-in
> modules.
>
> We know that several omap drivers are missing MODULE_ALIAS() and recently I've
> added it to all twl4030 drivers for that purpose.
>
> We can now rely that udev will correctly load the necessary module when we
> need it. And when I stated that there's no reason for not building
> everything as dynamic module for omaps, I was considering that we have
> enough memory in our boards and generaly developers will use NFS
> root file system anyways.
>
> I think this discussion is now way too long for something really
> simple: For development purposes on SDPs, dynamic linked modules
> can increase the development cycle by decreasing the amount of
> build/flash/reboot cycles.
Okay. End of discussion. :)
- Anand
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module
2008-06-26 8:31 ` Gadiyar, Anand
@ 2008-06-26 13:20 ` Tony Lindgren
0 siblings, 0 replies; 27+ messages in thread
From: Tony Lindgren @ 2008-06-26 13:20 UTC (permalink / raw)
To: Gadiyar, Anand
Cc: Felipe Balbi, igor.stoppa@nokia.com, Jouni Hogander,
linux-omap@vger.kernel.org
* Gadiyar, Anand <gadiyar@ti.com> [080626 11:33]:
> > > That wasn't what I said or meant. What I did want to bring out was that having
> > > something built-in might give it more exposure to test by someone who wasn't
> > > actively working on that area. And most bugs are caught by people other than
> > > the active developers.
> >
> > Not really, another usecase for modular kernel is that we don't wanna
> > add e.g. tea (radio) driver for n810 cuz it doesn't have that chip.
> > With modular kernel with proper MODULE_ALIAS() and udev, you just
> > flash the same kernel and modules in both n800 and n810 and tea driver
> > would only be probed in n800.
> >
> > I think this is what Igor meant when we said about validation across
> > boards.
>
> Ok. Fair enough. Point taken.
>
>
> > > At first glance to your email, I thought you had a valid point here. Thinking a
> > > little more, I think your point is valid only if you had a module that should not
> > > be loaded on a particular board. In such a case, you would anyway want to fix that
> > > module.
> >
> > Or you rely on udev rules and keep the main kernel code smaller.
> >
> > > Yes, having a modular kernel is useful. And it is probably the way to go. But please
> > > don't tell me that you can't do the same things with almost everything built-in.
> >
> > some stuff you really can't. If your mmc driver get stuck somewhere, you
> > can't modprobe -r -f omap_hsmmc and restart your work with a built-in
> > mmc driver. With modular kernel, we really can do it: forcefully remove
> > the driver and reset the controller, this would give us oportunity to
> > analyze logs and try again by reloading the module.
> >
> > With a built-in kernel, the only way out is reboot.
>
> Agreed.
>
> > > The 2430 defconfig has almost everything modular, while the 3430 defconfig doesn't.
> > > I propose we start a separate defconfig for the modular case or use allmodconfig.
> > > Maybe even have this as the defconfig for the multi-omap kernel. If we keep the
> > > individual defconfigs as a nearly all-built-in case, we can still get the best of
> > > both worlds.
> >
> > The thins is that normaly you'd have udev running anyways, and it would
> > automatically load modules based on /sys and correct MODULE_ALIAS()
> > and that's already another thing to test that can't be tested with built-in
> > modules.
> >
> > We know that several omap drivers are missing MODULE_ALIAS() and recently I've
> > added it to all twl4030 drivers for that purpose.
> >
> > We can now rely that udev will correctly load the necessary module when we
> > need it. And when I stated that there's no reason for not building
> > everything as dynamic module for omaps, I was considering that we have
> > enough memory in our boards and generaly developers will use NFS
> > root file system anyways.
> >
> > I think this discussion is now way too long for something really
> > simple: For development purposes on SDPs, dynamic linked modules
> > can increase the development cycle by decreasing the amount of
> > build/flash/reboot cycles.
>
> Okay. End of discussion. :)
Pushing Jouni's patch to make MMC a module today :)
Tony
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
2008-06-25 9:13 ` [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-26 2:30 ` Paul Walmsley
2008-06-27 8:59 ` Rajendra Nayak
2008-06-25 9:13 ` [PATCH 3/7] 34XX: PM: Workaround to reset all wkdeps Jouni Hogander
` (5 subsequent siblings)
7 siblings, 2 replies; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap
This workaround enables autoidle for interface clocks and plls. Also
automatic control of external oscillator through sys_clkreq is
enabled. I think these should be done by clockfw.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/pm34xx.c | 120 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 120 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index c7493f5..2dccd0b 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -332,6 +332,126 @@ static struct platform_suspend_ops omap_pm_ops = {
static void __init prcm_setup_regs(void)
{
+ /* XXX Enable interface clock autoidle for all modules. This
+ * should be done by clockfw */
+ cm_write_mod_reg(
+ OMAP3430ES2_AUTO_MMC3 |
+ OMAP3430ES2_AUTO_ICR |
+ OMAP3430_AUTO_AES2 |
+ OMAP3430_AUTO_SHA12 |
+ OMAP3430_AUTO_DES2 |
+ OMAP3430_AUTO_MMC2 |
+ OMAP3430_AUTO_MMC1 |
+ OMAP3430_AUTO_MSPRO |
+ OMAP3430_AUTO_HDQ |
+ OMAP3430_AUTO_MCSPI4 |
+ OMAP3430_AUTO_MCSPI3 |
+ OMAP3430_AUTO_MCSPI2 |
+ OMAP3430_AUTO_MCSPI1 |
+ OMAP3430_AUTO_I2C3 |
+ OMAP3430_AUTO_I2C2 |
+ OMAP3430_AUTO_I2C1 |
+ OMAP3430_AUTO_UART2 |
+ OMAP3430_AUTO_UART1 |
+ OMAP3430_AUTO_GPT11 |
+ OMAP3430_AUTO_GPT10 |
+ OMAP3430_AUTO_MCBSP5 |
+ OMAP3430_AUTO_MCBSP1 |
+ OMAP3430ES1_AUTO_FAC | /* This is es1 only */
+ OMAP3430_AUTO_MAILBOXES |
+ OMAP3430_AUTO_OMAPCTRL |
+ OMAP3430ES1_AUTO_FSHOSTUSB |
+ OMAP3430_AUTO_HSOTGUSB |
+ OMAP3430ES1_AUTO_D2D | /* This is es1 only */
+ OMAP3430_AUTO_SSI,
+ CORE_MOD, CM_AUTOIDLE1);
+
+ cm_write_mod_reg(
+ OMAP3430_AUTO_PKA |
+ OMAP3430_AUTO_AES1 |
+ OMAP3430_AUTO_RNG |
+ OMAP3430_AUTO_SHA11 |
+ OMAP3430_AUTO_DES1,
+ CORE_MOD, CM_AUTOIDLE2);
+
+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+ cm_write_mod_reg(
+ OMAP3430ES2_AUTO_USBTLL,
+ CORE_MOD, CM_AUTOIDLE3);
+ }
+
+ cm_write_mod_reg(
+ OMAP3430_AUTO_WDT2 |
+ OMAP3430_AUTO_WDT1 |
+ OMAP3430_AUTO_GPIO1 |
+ OMAP3430_AUTO_32KSYNC |
+ OMAP3430_AUTO_GPT12 |
+ OMAP3430_AUTO_GPT1 ,
+ WKUP_MOD, CM_AUTOIDLE);
+
+ cm_write_mod_reg(
+ OMAP3430_AUTO_DSS,
+ OMAP3430_DSS_MOD,
+ CM_AUTOIDLE);
+
+ cm_write_mod_reg(
+ OMAP3430_AUTO_CAM,
+ OMAP3430_CAM_MOD,
+ CM_AUTOIDLE);
+
+ cm_write_mod_reg(
+ OMAP3430_AUTO_GPIO6 |
+ OMAP3430_AUTO_GPIO5 |
+ OMAP3430_AUTO_GPIO4 |
+ OMAP3430_AUTO_GPIO3 |
+ OMAP3430_AUTO_GPIO2 |
+ OMAP3430_AUTO_WDT3 |
+ OMAP3430_AUTO_UART3 |
+ OMAP3430_AUTO_GPT9 |
+ OMAP3430_AUTO_GPT8 |
+ OMAP3430_AUTO_GPT7 |
+ OMAP3430_AUTO_GPT6 |
+ OMAP3430_AUTO_GPT5 |
+ OMAP3430_AUTO_GPT4 |
+ OMAP3430_AUTO_GPT3 |
+ OMAP3430_AUTO_GPT2 |
+ OMAP3430_AUTO_MCBSP4 |
+ OMAP3430_AUTO_MCBSP3 |
+ OMAP3430_AUTO_MCBSP2,
+ OMAP3430_PER_MOD,
+ CM_AUTOIDLE);
+
+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+ cm_write_mod_reg(
+ OMAP3430ES2_AUTO_USBHOST,
+ OMAP3430ES2_USBHOST_MOD,
+ CM_AUTOIDLE);
+ }
+
+ /* XXX Set all plls to autoidle. This is needed until autoidle is
+ * enabled by clockfw */
+ cm_write_mod_reg(1 << OMAP3430_CLKTRCTRL_IVA2_SHIFT,
+ OMAP3430_IVA2_MOD,
+ CM_AUTOIDLE2);
+ cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
+ MPU_MOD,
+ CM_AUTOIDLE2);
+ cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
+ (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
+ PLL_MOD,
+ CM_AUTOIDLE);
+ cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
+ PLL_MOD,
+ CM_AUTOIDLE2);
+
+ /* XXX Enable control of expternal oscillator through
+ * sys_clkreq. I think clockfw should provide means to do this
+ */
+ prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
+ 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+
/* setup wakup source */
prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1,
WKUP_MOD, PM_WKEN);
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls
2008-06-25 9:13 ` [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
@ 2008-06-26 2:30 ` Paul Walmsley
2008-06-27 8:59 ` Rajendra Nayak
1 sibling, 0 replies; 27+ messages in thread
From: Paul Walmsley @ 2008-06-26 2:30 UTC (permalink / raw)
To: Jouni Hogander; +Cc: linux-omap
Hello Jouni,
On Wed, 25 Jun 2008, Jouni Hogander wrote:
> + /* XXX Set all plls to autoidle. This is needed until autoidle is
> + * enabled by clockfw */
> + cm_write_mod_reg(1 << OMAP3430_CLKTRCTRL_IVA2_SHIFT,
> + OMAP3430_IVA2_MOD,
> + CM_AUTOIDLE2);
> + cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
> + MPU_MOD,
> + CM_AUTOIDLE2);
> + cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
> + (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
> + PLL_MOD,
> + CM_AUTOIDLE);
> + cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
> + PLL_MOD,
> + CM_AUTOIDLE2);
for the DPLLs, there is code to do this already in the clock framework -
see omap3_dpll_allow_idle() in arch/arm/mach-omap2/clock34xx.c
- Paul
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls
2008-06-25 9:13 ` [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
2008-06-26 2:30 ` Paul Walmsley
@ 2008-06-27 8:59 ` Rajendra Nayak
2008-06-27 9:08 ` Högander Jouni
1 sibling, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2008-06-27 8:59 UTC (permalink / raw)
To: 'Jouni Hogander', linux-omap
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org
> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Jouni Hogander
> Sent: Wednesday, June 25, 2008 2:44 PM
> To: linux-omap@vger.kernel.org
> Subject: [PATCH 2/7] 34XX: PM: Workaround to enable autoidle
> for clocks and plls
>
> This workaround enables autoidle for interface clocks and plls. Also
> automatic control of external oscillator through sys_clkreq is
> enabled. I think these should be done by clockfw.
>
> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> ---
> arch/arm/mach-omap2/pm34xx.c | 120
> ++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 120 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c
> b/arch/arm/mach-omap2/pm34xx.c
> index c7493f5..2dccd0b 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -332,6 +332,126 @@ static struct platform_suspend_ops
> omap_pm_ops = {
>
> static void __init prcm_setup_regs(void)
> {
> + /* XXX Enable interface clock autoidle for all modules. This
> + * should be done by clockfw */
> + cm_write_mod_reg(
> + OMAP3430ES2_AUTO_MMC3 |
> + OMAP3430ES2_AUTO_ICR |
> + OMAP3430_AUTO_AES2 |
> + OMAP3430_AUTO_SHA12 |
> + OMAP3430_AUTO_DES2 |
> + OMAP3430_AUTO_MMC2 |
> + OMAP3430_AUTO_MMC1 |
> + OMAP3430_AUTO_MSPRO |
> + OMAP3430_AUTO_HDQ |
> + OMAP3430_AUTO_MCSPI4 |
> + OMAP3430_AUTO_MCSPI3 |
> + OMAP3430_AUTO_MCSPI2 |
> + OMAP3430_AUTO_MCSPI1 |
> + OMAP3430_AUTO_I2C3 |
> + OMAP3430_AUTO_I2C2 |
> + OMAP3430_AUTO_I2C1 |
> + OMAP3430_AUTO_UART2 |
> + OMAP3430_AUTO_UART1 |
> + OMAP3430_AUTO_GPT11 |
> + OMAP3430_AUTO_GPT10 |
> + OMAP3430_AUTO_MCBSP5 |
> + OMAP3430_AUTO_MCBSP1 |
> + OMAP3430ES1_AUTO_FAC | /* This is es1 only */
> + OMAP3430_AUTO_MAILBOXES |
> + OMAP3430_AUTO_OMAPCTRL |
> + OMAP3430ES1_AUTO_FSHOSTUSB |
> + OMAP3430_AUTO_HSOTGUSB |
> + OMAP3430ES1_AUTO_D2D | /* This is es1 only */
> + OMAP3430_AUTO_SSI,
> + CORE_MOD, CM_AUTOIDLE1);
> +
> + cm_write_mod_reg(
> + OMAP3430_AUTO_PKA |
> + OMAP3430_AUTO_AES1 |
> + OMAP3430_AUTO_RNG |
> + OMAP3430_AUTO_SHA11 |
> + OMAP3430_AUTO_DES1,
> + CORE_MOD, CM_AUTOIDLE2);
> +
> + if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> + cm_write_mod_reg(
> + OMAP3430ES2_AUTO_USBTLL,
> + CORE_MOD, CM_AUTOIDLE3);
> + }
> +
> + cm_write_mod_reg(
> + OMAP3430_AUTO_WDT2 |
> + OMAP3430_AUTO_WDT1 |
> + OMAP3430_AUTO_GPIO1 |
> + OMAP3430_AUTO_32KSYNC |
> + OMAP3430_AUTO_GPT12 |
> + OMAP3430_AUTO_GPT1 ,
> + WKUP_MOD, CM_AUTOIDLE);
> +
> + cm_write_mod_reg(
> + OMAP3430_AUTO_DSS,
> + OMAP3430_DSS_MOD,
> + CM_AUTOIDLE);
> +
> + cm_write_mod_reg(
> + OMAP3430_AUTO_CAM,
> + OMAP3430_CAM_MOD,
> + CM_AUTOIDLE);
> +
> + cm_write_mod_reg(
> + OMAP3430_AUTO_GPIO6 |
> + OMAP3430_AUTO_GPIO5 |
> + OMAP3430_AUTO_GPIO4 |
> + OMAP3430_AUTO_GPIO3 |
> + OMAP3430_AUTO_GPIO2 |
> + OMAP3430_AUTO_WDT3 |
> + OMAP3430_AUTO_UART3 |
> + OMAP3430_AUTO_GPT9 |
> + OMAP3430_AUTO_GPT8 |
> + OMAP3430_AUTO_GPT7 |
> + OMAP3430_AUTO_GPT6 |
> + OMAP3430_AUTO_GPT5 |
> + OMAP3430_AUTO_GPT4 |
> + OMAP3430_AUTO_GPT3 |
> + OMAP3430_AUTO_GPT2 |
> + OMAP3430_AUTO_MCBSP4 |
> + OMAP3430_AUTO_MCBSP3 |
> + OMAP3430_AUTO_MCBSP2,
> + OMAP3430_PER_MOD,
> + CM_AUTOIDLE);
> +
> + if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> + cm_write_mod_reg(
> + OMAP3430ES2_AUTO_USBHOST,
> + OMAP3430ES2_USBHOST_MOD,
> + CM_AUTOIDLE);
> + }
> +
> + /* XXX Set all plls to autoidle. This is needed until
> autoidle is
> + * enabled by clockfw */
> + cm_write_mod_reg(1 << OMAP3430_CLKTRCTRL_IVA2_SHIFT,
> + OMAP3430_IVA2_MOD,
> + CM_AUTOIDLE2);
> + cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
> + MPU_MOD,
> + CM_AUTOIDLE2);
> + cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
> + (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
> + PLL_MOD,
> + CM_AUTOIDLE);
> + cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
> + PLL_MOD,
> + CM_AUTOIDLE2);
> +
> + /* XXX Enable control of expternal oscillator through
> + * sys_clkreq. I think clockfw should provide means to do this
> + */
> + prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
> + 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
> + OMAP3430_GR_MOD,
> + OMAP3_PRM_CLKSRC_CTRL_OFFSET);
> +
> /* setup wakup source */
> prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 |
> OMAP3430_EN_GPT1,
> WKUP_MOD, PM_WKEN);
The previous patchset also has this function enable the D2D clock domain H/w supervised.
Is this now done some other place? Not doing this gates CORE RET/OFF.
if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
/* This hack is taken from ti code. There is no usb clkdm in
* core, but this still needs to be written: allow idle of usb
* clkdm? */
v = cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
v |= 0x30;
cm_write_mod_reg(v, CORE_MOD, CM_CLKSTCTRL);
}
> --
> 1.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls
2008-06-27 8:59 ` Rajendra Nayak
@ 2008-06-27 9:08 ` Högander Jouni
0 siblings, 0 replies; 27+ messages in thread
From: Högander Jouni @ 2008-06-27 9:08 UTC (permalink / raw)
To: ext Rajendra Nayak; +Cc: linux-omap
"ext Rajendra Nayak" <rnayak@ti.com> writes:
>> /* setup wakup source */
>> prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 |
>> OMAP3430_EN_GPT1,
>> WKUP_MOD, PM_WKEN);
>
> The previous patchset also has this function enable the D2D clock domain H/w supervised.
> Is this now done some other place? Not doing this gates CORE
> RET/OFF.
d2d clkdm wasn't earlier handled by clkdm code in case of silicon rev >
ES1, bacause it is not documented to exist in them. Now it is handled
by clkdm/pwrdm code and idle is allowed same way as for other clkdms.
>
> if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> /* This hack is taken from ti code. There is no usb clkdm in
> * core, but this still needs to be written: allow idle of usb
> * clkdm? */
> v = cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
> v |= 0x30;
> cm_write_mod_reg(v, CORE_MOD, CM_CLKSTCTRL);
> }
>
>> --
>> 1.5.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe
>> linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
--
Jouni Högander
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 3/7] 34XX: PM: Workaround to reset all wkdeps
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
2008-06-25 9:13 ` [PATCH 1/7] 34XX: PM: Workaround to build omap hsmmc as a module Jouni Hogander
2008-06-25 9:13 ` [PATCH 2/7] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-25 9:13 ` [PATCH 4/7] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
` (4 subsequent siblings)
7 siblings, 0 replies; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap
This workaround is needed until powerdomain code resets wkdeps.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/pm34xx.c | 20 ++++++++++++++++++--
1 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 2dccd0b..dc2e57d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -332,6 +332,20 @@ static struct platform_suspend_ops omap_pm_ops = {
static void __init prcm_setup_regs(void)
{
+ /* XXX Reset all wkdeps. This should be done when initializing
+ * powerdomains */
+ prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+ prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
+ prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
+ } else
+ prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
+
/* XXX Enable interface clock autoidle for all modules. This
* should be done by clockfw */
cm_write_mod_reg(
@@ -487,6 +501,10 @@ int __init omap3_pm_init(void)
printk(KERN_ERR "Power Management for TI OMAP3.\n");
+ /* XXX prcm_setup_regs needs to be before enabling hw
+ * supervised mode for powerdomains */
+ prcm_setup_regs();
+
ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
(irq_handler_t)prcm_interrupt_handler,
IRQF_DISABLED, "prcm", NULL);
@@ -513,8 +531,6 @@ int __init omap3_pm_init(void)
suspend_set_ops(&omap_pm_ops);
- prcm_setup_regs();
-
pm_idle = omap3_pm_idle;
err1:
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 4/7] 34XX: PM: Workaround to check wether any fck is active before entering sleep
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
` (2 preceding siblings ...)
2008-06-25 9:13 ` [PATCH 3/7] 34XX: PM: Workaround to reset all wkdeps Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-25 9:13 ` [PATCH 5/7] OMAP: PM: Add new sysfs option for disabling clocks when entering idle Jouni Hogander
` (3 subsequent siblings)
7 siblings, 0 replies; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap
This workaround shouldn't be needed when all drivers are configuring
their sysconfig registers properly and using their clocks properly.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/pm34xx.c | 31 +++++++++++++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index dc2e57d..edde254 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -174,10 +174,41 @@ static void omap_sram_idle(void)
omap2_gpio_resume_after_retention();
}
+static int omap3_fclks_active(void)
+{
+ u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
+ fck_cam = 0, fck_per = 0, fck_usbhost = 0;
+
+ fck_core1 = cm_read_mod_reg(CORE_MOD,
+ CM_FCLKEN1);
+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+ fck_core3 = cm_read_mod_reg(CORE_MOD,
+ OMAP3430ES2_CM_FCLKEN3);
+ fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+ CM_FCLKEN);
+ fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+ CM_FCLKEN);
+ } else
+ fck_sgx = cm_read_mod_reg(GFX_MOD,
+ OMAP3430ES2_CM_FCLKEN3);
+ fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
+ CM_FCLKEN);
+ fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
+ CM_FCLKEN);
+ fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
+ CM_FCLKEN);
+ if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
+ fck_cam | fck_per | fck_usbhost)
+ return 1;
+ return 0;
+}
+
static int omap3_can_sleep(void)
{
if (!enable_dyn_sleep)
return 0;
+ if (omap3_fclks_active())
+ return 0;
if (atomic_read(&sleep_block) > 0)
return 0;
return 1;
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 5/7] OMAP: PM: Add new sysfs option for disabling clocks when entering idle
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
` (3 preceding siblings ...)
2008-06-25 9:13 ` [PATCH 4/7] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-25 9:13 ` [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks Jouni Hogander
` (2 subsequent siblings)
7 siblings, 0 replies; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap
There are drivers that are not disabling their clocks (gpio &
uart). These clocks need to be disabled if retention/off state is
wanted when idling. Before disabling them in idle loop this option
needs to be checked.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/pm.c | 37 +++++++++++++++++++++++++++++++------
arch/arm/mach-omap2/pm.h | 1 +
2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index bef58d7..b7434df 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -31,30 +31,51 @@
#include "pm.h"
unsigned short enable_dyn_sleep;
+unsigned short clocks_off_while_idle;
atomic_t sleep_block = ATOMIC_INIT(0);
+static ssize_t idle_show(struct kobject *, struct kobj_attribute *, char *);
+static ssize_t idle_store(struct kobject *k, struct kobj_attribute *,
+ const char *buf, size_t n);
+
+static struct kobj_attribute sleep_while_idle_attr =
+ __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
+
+static struct kobj_attribute clocks_off_while_idle_attr =
+ __ATTR(clocks_off_while_idle, 0644, idle_show, idle_store);
+
static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
- return sprintf(buf, "%hu\n", enable_dyn_sleep);
+ if (attr == &sleep_while_idle_attr)
+ return sprintf(buf, "%hu\n", enable_dyn_sleep);
+ else if (attr == &clocks_off_while_idle_attr)
+ return sprintf(buf, "%hu\n", clocks_off_while_idle);
+ else
+ return -EINVAL;
}
static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
unsigned short value;
+
if (sscanf(buf, "%hu", &value) != 1 ||
(value != 0 && value != 1)) {
- printk(KERN_ERR "idle_sleep_store: Invalid value\n");
+ printk(KERN_ERR "idle_store: Invalid value\n");
return -EINVAL;
}
- enable_dyn_sleep = value;
+
+ if (attr == &sleep_while_idle_attr)
+ enable_dyn_sleep = value;
+ else if (attr == &clocks_off_while_idle_attr)
+ clocks_off_while_idle = value;
+ else
+ return -EINVAL;
+
return n;
}
-static struct kobj_attribute sleep_while_idle_attr =
- __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
-
void omap2_block_sleep(void)
{
atomic_inc(&sleep_block);
@@ -86,6 +107,10 @@ int __init omap_pm_init(void)
error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr);
if (error)
printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
+ error = sysfs_create_file(power_kobj,
+ &clocks_off_while_idle_attr.attr);
+ if (error)
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
return error;
}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 351456e..0aeb461 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -17,6 +17,7 @@ extern int omap2_pm_init(void);
extern int omap3_pm_init(void);
extern unsigned short enable_dyn_sleep;
+extern unsigned short clocks_off_while_idle;
extern atomic_t sleep_block;
#ifdef CONFIG_PM_DEBUG
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
` (4 preceding siblings ...)
2008-06-25 9:13 ` [PATCH 5/7] OMAP: PM: Add new sysfs option for disabling clocks when entering idle Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-26 11:54 ` Rajendra Nayak
2008-06-25 9:13 ` [PATCH 7/7] Added sleep support to UART Jouni Hogander
2008-06-25 11:38 ` [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Rajendra Nayak
7 siblings, 1 reply; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap
In omap3 gpios 2-6 are in per domain. Clocks for these should be
disabled. This patch is needed until gpio driver disables gpio clocks.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/pm34xx.c | 15 +++++++-
arch/arm/mach-omap2/sleep34xx.S | 74 +++++++++++++++++++++++++++++++++++++++
2 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index edde254..9c7b7be 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -47,12 +47,19 @@ struct power_state {
static LIST_HEAD(pwrst_list);
-void (*_omap_sram_idle)(u32 *addr, int save_state);
+void (*_omap_sram_idle)(u32 *addr, int save_state, int disable_clocks);
static void (*saved_idle)(void);
static struct powerdomain *mpu_pwrdm;
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void gpio_fclk_mask(u32 *fclk)
+{
+ *fclk &= ~(0x1f << 13);
+}
+
/* PRCM Interrupt Handler for wakeups */
static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
{
@@ -169,7 +176,7 @@ static void omap_sram_idle(void)
omap2_gpio_prepare_for_retention();
- _omap_sram_idle(NULL, save_state);
+ _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
omap2_gpio_resume_after_retention();
}
@@ -197,6 +204,10 @@ static int omap3_fclks_active(void)
CM_FCLKEN);
fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
CM_FCLKEN);
+
+ if (clocks_off_while_idle)
+ gpio_fclk_mask(&fck_per);
+
if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
fck_cam | fck_per | fck_usbhost)
return 1;
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index ebc7eb3..1f7009a 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -32,6 +32,8 @@
#include "prm.h"
#include "sdrc.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
OMAP3430_PM_PREPWSTST)
@@ -45,6 +47,15 @@
SCRATCHPAD_MEM_OFFS)
#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
+/* XXX gpio fclk workaround */
+#define CM_FCLKEN_PER_V OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD, \
+ CM_FCLKEN)
+#define CM_FCLKEN_PER_P io_v2p(CM_FCLKEN_PER_V)
+
+#define GPIO_FCLK_MASK OMAP3430_EN_GPIO6 | OMAP3430_EN_GPIO5 | \
+ OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO3 | \
+ OMAP3430_EN_GPIO2
+
.text
/* Function call to get the restore pointer for resume from OFF */
ENTRY(get_restore_pointer)
@@ -68,14 +79,41 @@ loop:
/*b loop*/ @Enable to debug by stepping through code
/* r0 contains restore pointer in sdram */
/* r1 contains information about saving context */
+ /* r2 contains information whether clocks should be disabled */
ldr r4, sdrc_power @ read the SDRC_POWER register
ldr r5, [r4] @ read the contents of SDRC_POWER
orr r5, r5, #0x40 @ enable self refresh on idle req
str r5, [r4] @ write back to SDRC_POWER register
+ /* XXX gpio fclk workaround */
+ /* Check if per fclken needs to be saved */
+ cmp r2, #0x0
+ beq skip_per_fclken_save
+
+ /* XXX gpio fclk workaround */
+ /* Save current value of per fclken reg */
+ ldr r4, cm_fclken_per_v
+ ldr r5, [r4]
+ str r5, cm_fclken_per_val
+skip_per_fclken_save:
+
cmp r1, #0x0
/* If context save is required, do that and execute wfi */
bne save_context_wfi
+
+ /* XXX gpio fclk workaround */
+ /* Check if gpio clocks needs to be disabled */
+ ldr r5, cm_fclken_per_val
+ cmp r5, #0x0
+ beq skip_gpio_clk_disable
+
+ /* XXX gpio fclk workaround */
+ /* Disable gpio clocks */
+ ldr r4, cm_fclken_per_v
+ bic r5, r5, #GPIO_FCLK_MASK
+ str r5, [r4]
+skip_gpio_clk_disable:
+
/* Data memory barrier and Data sync barrier */
mov r1, #0
mcr p15, 0, r1, c7, c10, 4
@@ -93,6 +131,14 @@ loop:
nop
nop
nop
+
+ /* XXX gpio fclk workaround */
+ ldr r5, cm_fclken_per_val
+ cmp r5, #0x0
+ beq skip_per_fclken_restore
+ str r5, [r4]
+skip_per_fclken_restore:
+
bl i_dll_wait
ldmfd sp!, {r0-r12, pc} @ restore regs and return
@@ -483,6 +529,20 @@ finished:
mcr p15, 2, r10, c0, c0, 0
isb
skip_l2_inval:
+
+ /* XXX gpio fclk workaround */
+ /* Check if gpio clocks needs to be disabled */
+ ldr r5, cm_fclken_per_val
+ cmp r5, #0x0
+ beq skip_gpio_clk_disable_2
+
+ /* XXX gpio fclk workaround */
+ /* Disable gpio clocks */
+ ldr r4, cm_fclken_per_p
+ bic r5, r5, #GPIO_FCLK_MASK
+ str r5, [r4]
+skip_gpio_clk_disable_2:
+
/* Data memory barrier and Data sync barrier */
mov r1, #0
mcr p15, 0, r1, c7, c10, 4
@@ -499,6 +559,14 @@ skip_l2_inval:
nop
nop
nop
+
+ /* XXX gpio fclk workaround */
+ ldr r5, cm_fclken_per_val
+ cmp r5, #0x0
+ beq skip_per_fclken_restore_2
+ str r5, [r4]
+skip_per_fclken_restore_2:
+
bl i_dll_wait
/* restore regs and return */
ldmfd sp!, {r0-r12, pc}
@@ -540,5 +608,11 @@ table_entry:
.word 0x00000C02
cache_pred_disable_mask:
.word 0xFFFFE7FB
+cm_fclken_per_v:
+ .word CM_FCLKEN_PER_V
+cm_fclken_per_p:
+ .word CM_FCLKEN_PER_P
+cm_fclken_per_val:
+ .word 0
ENTRY(omap34xx_cpu_suspend_sz)
.word . - omap34xx_cpu_suspend
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* RE: [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks
2008-06-25 9:13 ` [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks Jouni Hogander
@ 2008-06-26 11:54 ` Rajendra Nayak
2008-06-26 12:16 ` Högander Jouni
0 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2008-06-26 11:54 UTC (permalink / raw)
To: 'Jouni Hogander', linux-omap
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org
> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Jouni Hogander
> Sent: Wednesday, June 25, 2008 2:44 PM
> To: linux-omap@vger.kernel.org
> Subject: [PATCH 6/7] 34XX: PM: Workaround for taking care of
> gpio clocks
>
> In omap3 gpios 2-6 are in per domain. Clocks for these should be
> disabled. This patch is needed until gpio driver disables gpio clocks.
>
> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> ---
> arch/arm/mach-omap2/pm34xx.c | 15 +++++++-
> arch/arm/mach-omap2/sleep34xx.S | 74
> +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c
> b/arch/arm/mach-omap2/pm34xx.c
> index edde254..9c7b7be 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -47,12 +47,19 @@ struct power_state {
>
> static LIST_HEAD(pwrst_list);
>
> -void (*_omap_sram_idle)(u32 *addr, int save_state);
> +void (*_omap_sram_idle)(u32 *addr, int save_state, int
> disable_clocks);
>
> static void (*saved_idle)(void);
>
> static struct powerdomain *mpu_pwrdm;
>
> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> + * handles fcks correctly */
> +static void gpio_fclk_mask(u32 *fclk)
> +{
> + *fclk &= ~(0x1f << 13);
> +}
> +
> /* PRCM Interrupt Handler for wakeups */
> static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
> {
> @@ -169,7 +176,7 @@ static void omap_sram_idle(void)
>
> omap2_gpio_prepare_for_retention();
>
> - _omap_sram_idle(NULL, save_state);
> + _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
>
> omap2_gpio_resume_after_retention();
> }
> @@ -197,6 +204,10 @@ static int omap3_fclks_active(void)
> CM_FCLKEN);
> fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
> CM_FCLKEN);
> +
> + if (clocks_off_while_idle)
> + gpio_fclk_mask(&fck_per);
> +
> if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
> fck_cam | fck_per | fck_usbhost)
> return 1;
> diff --git a/arch/arm/mach-omap2/sleep34xx.S
> b/arch/arm/mach-omap2/sleep34xx.S
> index ebc7eb3..1f7009a 100644
> --- a/arch/arm/mach-omap2/sleep34xx.S
> +++ b/arch/arm/mach-omap2/sleep34xx.S
> @@ -32,6 +32,8 @@
>
> #include "prm.h"
> #include "sdrc.h"
> +#include "cm.h"
> +#include "cm-regbits-34xx.h"
>
> #define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
> OMAP3430_PM_PREPWSTST)
> @@ -45,6 +47,15 @@
> SCRATCHPAD_MEM_OFFS)
> #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
>
> +/* XXX gpio fclk workaround */
> +#define CM_FCLKEN_PER_V
> OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD, \
> + CM_FCLKEN)
> +#define CM_FCLKEN_PER_P io_v2p(CM_FCLKEN_PER_V)
> +
> +#define GPIO_FCLK_MASK OMAP3430_EN_GPIO6 |
> OMAP3430_EN_GPIO5 | \
> + OMAP3430_EN_GPIO4 |
> OMAP3430_EN_GPIO3 | \
> + OMAP3430_EN_GPIO2
> +
> .text
> /* Function call to get the restore pointer for resume from OFF */
> ENTRY(get_restore_pointer)
> @@ -68,14 +79,41 @@ loop:
> /*b loop*/ @Enable to debug by stepping through code
> /* r0 contains restore pointer in sdram */
> /* r1 contains information about saving context */
> + /* r2 contains information whether clocks should be disabled */
> ldr r4, sdrc_power @ read the SDRC_POWER register
> ldr r5, [r4] @ read the contents of
> SDRC_POWER
> orr r5, r5, #0x40 @ enable self refresh
> on idle req
> str r5, [r4] @ write back to
> SDRC_POWER register
>
> + /* XXX gpio fclk workaround */
> + /* Check if per fclken needs to be saved */
> + cmp r2, #0x0
> + beq skip_per_fclken_save
> +
> + /* XXX gpio fclk workaround */
> + /* Save current value of per fclken reg */
> + ldr r4, cm_fclken_per_v
> + ldr r5, [r4]
> + str r5, cm_fclken_per_val
> +skip_per_fclken_save:
> +
Any reason why this is now done in SRAM?
> cmp r1, #0x0
> /* If context save is required, do that and execute wfi */
> bne save_context_wfi
In case of OFF mode, clocks would never be disabled.
> +
> + /* XXX gpio fclk workaround */
> + /* Check if gpio clocks needs to be disabled */
> + ldr r5, cm_fclken_per_val
> + cmp r5, #0x0
> + beq skip_gpio_clk_disable
> +
> + /* XXX gpio fclk workaround */
> + /* Disable gpio clocks */
> + ldr r4, cm_fclken_per_v
> + bic r5, r5, #GPIO_FCLK_MASK
> + str r5, [r4]
> +skip_gpio_clk_disable:
Even with clocks_off_while_idle set to 1, should'nt gpio clocks be cut and restored only
when a PER RET/OFF is attemted and not every time omap_sram_idle is called?
> +
> /* Data memory barrier and Data sync barrier */
> mov r1, #0
> mcr p15, 0, r1, c7, c10, 4
> @@ -93,6 +131,14 @@ loop:
> nop
> nop
> nop
> +
> + /* XXX gpio fclk workaround */
> + ldr r5, cm_fclken_per_val
> + cmp r5, #0x0
> + beq skip_per_fclken_restore
> + str r5, [r4]
> +skip_per_fclken_restore:
> +
> bl i_dll_wait
>
> ldmfd sp!, {r0-r12, pc} @ restore regs
> and return
> @@ -483,6 +529,20 @@ finished:
> mcr p15, 2, r10, c0, c0, 0
> isb
> skip_l2_inval:
> +
> + /* XXX gpio fclk workaround */
> + /* Check if gpio clocks needs to be disabled */
> + ldr r5, cm_fclken_per_val
> + cmp r5, #0x0
> + beq skip_gpio_clk_disable_2
> +
> + /* XXX gpio fclk workaround */
> + /* Disable gpio clocks */
> + ldr r4, cm_fclken_per_p
> + bic r5, r5, #GPIO_FCLK_MASK
> + str r5, [r4]
> +skip_gpio_clk_disable_2:
> +
> /* Data memory barrier and Data sync barrier */
> mov r1, #0
> mcr p15, 0, r1, c7, c10, 4
> @@ -499,6 +559,14 @@ skip_l2_inval:
> nop
> nop
> nop
> +
> + /* XXX gpio fclk workaround */
> + ldr r5, cm_fclken_per_val
> + cmp r5, #0x0
> + beq skip_per_fclken_restore_2
> + str r5, [r4]
> +skip_per_fclken_restore_2:
> +
> bl i_dll_wait
> /* restore regs and return */
> ldmfd sp!, {r0-r12, pc}
> @@ -540,5 +608,11 @@ table_entry:
> .word 0x00000C02
> cache_pred_disable_mask:
> .word 0xFFFFE7FB
> +cm_fclken_per_v:
> + .word CM_FCLKEN_PER_V
> +cm_fclken_per_p:
> + .word CM_FCLKEN_PER_P
> +cm_fclken_per_val:
> + .word 0
> ENTRY(omap34xx_cpu_suspend_sz)
> .word . - omap34xx_cpu_suspend
> --
> 1.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks
2008-06-26 11:54 ` Rajendra Nayak
@ 2008-06-26 12:16 ` Högander Jouni
2008-06-26 12:30 ` Rajendra Nayak
0 siblings, 1 reply; 27+ messages in thread
From: Högander Jouni @ 2008-06-26 12:16 UTC (permalink / raw)
To: ext Rajendra Nayak; +Cc: linux-omap
"ext Rajendra Nayak" <rnayak@ti.com> writes:
>
>
>> -----Original Message-----
>> From: linux-omap-owner@vger.kernel.org
>> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Jouni Hogander
>> Sent: Wednesday, June 25, 2008 2:44 PM
>> To: linux-omap@vger.kernel.org
>> Subject: [PATCH 6/7] 34XX: PM: Workaround for taking care of
>> gpio clocks
>>
>> In omap3 gpios 2-6 are in per domain. Clocks for these should be
>> disabled. This patch is needed until gpio driver disables gpio clocks.
>>
>> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
>> ---
>> arch/arm/mach-omap2/pm34xx.c | 15 +++++++-
>> arch/arm/mach-omap2/sleep34xx.S | 74
>> +++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 87 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/pm34xx.c
>> b/arch/arm/mach-omap2/pm34xx.c
>> index edde254..9c7b7be 100644
>> --- a/arch/arm/mach-omap2/pm34xx.c
>> +++ b/arch/arm/mach-omap2/pm34xx.c
>> @@ -47,12 +47,19 @@ struct power_state {
>>
>> static LIST_HEAD(pwrst_list);
>>
>> -void (*_omap_sram_idle)(u32 *addr, int save_state);
>> +void (*_omap_sram_idle)(u32 *addr, int save_state, int
>> disable_clocks);
>>
>> static void (*saved_idle)(void);
>>
>> static struct powerdomain *mpu_pwrdm;
>>
>> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
>> + * handles fcks correctly */
>> +static void gpio_fclk_mask(u32 *fclk)
>> +{
>> + *fclk &= ~(0x1f << 13);
>> +}
>> +
>> /* PRCM Interrupt Handler for wakeups */
>> static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
>> {
>> @@ -169,7 +176,7 @@ static void omap_sram_idle(void)
>>
>> omap2_gpio_prepare_for_retention();
>>
>> - _omap_sram_idle(NULL, save_state);
>> + _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
>>
>> omap2_gpio_resume_after_retention();
>> }
>> @@ -197,6 +204,10 @@ static int omap3_fclks_active(void)
>> CM_FCLKEN);
>> fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
>> CM_FCLKEN);
>> +
>> + if (clocks_off_while_idle)
>> + gpio_fclk_mask(&fck_per);
>> +
>> if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
>> fck_cam | fck_per | fck_usbhost)
>> return 1;
>> diff --git a/arch/arm/mach-omap2/sleep34xx.S
>> b/arch/arm/mach-omap2/sleep34xx.S
>> index ebc7eb3..1f7009a 100644
>> --- a/arch/arm/mach-omap2/sleep34xx.S
>> +++ b/arch/arm/mach-omap2/sleep34xx.S
>> @@ -32,6 +32,8 @@
>>
>> #include "prm.h"
>> #include "sdrc.h"
>> +#include "cm.h"
>> +#include "cm-regbits-34xx.h"
>>
>> #define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
>> OMAP3430_PM_PREPWSTST)
>> @@ -45,6 +47,15 @@
>> SCRATCHPAD_MEM_OFFS)
>> #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
>>
>> +/* XXX gpio fclk workaround */
>> +#define CM_FCLKEN_PER_V
>> OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD, \
>> + CM_FCLKEN)
>> +#define CM_FCLKEN_PER_P io_v2p(CM_FCLKEN_PER_V)
>> +
>> +#define GPIO_FCLK_MASK OMAP3430_EN_GPIO6 |
>> OMAP3430_EN_GPIO5 | \
>> + OMAP3430_EN_GPIO4 |
>> OMAP3430_EN_GPIO3 | \
>> + OMAP3430_EN_GPIO2
>> +
>> .text
>> /* Function call to get the restore pointer for resume from OFF */
>> ENTRY(get_restore_pointer)
>> @@ -68,14 +79,41 @@ loop:
>> /*b loop*/ @Enable to debug by stepping through code
>> /* r0 contains restore pointer in sdram */
>> /* r1 contains information about saving context */
>> + /* r2 contains information whether clocks should be disabled */
>> ldr r4, sdrc_power @ read the SDRC_POWER register
>> ldr r5, [r4] @ read the contents of
>> SDRC_POWER
>> orr r5, r5, #0x40 @ enable self refresh
>> on idle req
>> str r5, [r4] @ write back to
>> SDRC_POWER register
>>
>> + /* XXX gpio fclk workaround */
>> + /* Check if per fclken needs to be saved */
>> + cmp r2, #0x0
>> + beq skip_per_fclken_save
>> +
>> + /* XXX gpio fclk workaround */
>> + /* Save current value of per fclken reg */
>> + ldr r4, cm_fclken_per_v
>> + ldr r5, [r4]
>> + str r5, cm_fclken_per_val
>> +skip_per_fclken_save:
>> +
>
> Any reason why this is now done in SRAM?
Because of the fact that gpios in per domain are not able to generate
wakeup/interrupt if per domain is not active. We want to put per
domain into sleep state as late as possible. IOPAD wakeup starts to
work only after mpu enters its sleep state.
>
>> cmp r1, #0x0
>> /* If context save is required, do that and execute wfi */
>> bne save_context_wfi
>
> In case of OFF mode, clocks would never be disabled.
Isn't it done below. I might be wrong because I haven't been able to
test this with off mode.
>
>> +
>> + /* XXX gpio fclk workaround */
>> + /* Check if gpio clocks needs to be disabled */
>> + ldr r5, cm_fclken_per_val
>> + cmp r5, #0x0
>> + beq skip_gpio_clk_disable
>> +
>> + /* XXX gpio fclk workaround */
>> + /* Disable gpio clocks */
>> + ldr r4, cm_fclken_per_v
>> + bic r5, r5, #GPIO_FCLK_MASK
>> + str r5, [r4]
>> +skip_gpio_clk_disable:
>
> Even with clocks_off_while_idle set to 1, should'nt gpio clocks be cut and restored only
> when a PER RET/OFF is attemted and not every time omap_sram_idle is
> called?
Where this would then happen if not in sram? I mean gpio clock control
is not in current gpio code and adding that into it needs huge
effort. I'm not sure if it can be even handled there, because of this
wakeup problem. Basically we have this need to keep per gpios active
as long as possible, because after disabling their clocks they wont
generate interrupts/wakeups until mpu is in ret or off mode.
>
>> +
>> /* Data memory barrier and Data sync barrier */
>> mov r1, #0
>> mcr p15, 0, r1, c7, c10, 4
>> @@ -93,6 +131,14 @@ loop:
>> nop
>> nop
>> nop
>> +
>> + /* XXX gpio fclk workaround */
>> + ldr r5, cm_fclken_per_val
>> + cmp r5, #0x0
>> + beq skip_per_fclken_restore
>> + str r5, [r4]
>> +skip_per_fclken_restore:
>> +
>> bl i_dll_wait
>>
>> ldmfd sp!, {r0-r12, pc} @ restore regs
>> and return
>> @@ -483,6 +529,20 @@ finished:
>> mcr p15, 2, r10, c0, c0, 0
>> isb
>> skip_l2_inval:
>> +
>> + /* XXX gpio fclk workaround */
>> + /* Check if gpio clocks needs to be disabled */
>> + ldr r5, cm_fclken_per_val
>> + cmp r5, #0x0
>> + beq skip_gpio_clk_disable_2
>> +
>> + /* XXX gpio fclk workaround */
>> + /* Disable gpio clocks */
>> + ldr r4, cm_fclken_per_p
>> + bic r5, r5, #GPIO_FCLK_MASK
>> + str r5, [r4]
>> +skip_gpio_clk_disable_2:
>> +
>> /* Data memory barrier and Data sync barrier */
>> mov r1, #0
>> mcr p15, 0, r1, c7, c10, 4
>> @@ -499,6 +559,14 @@ skip_l2_inval:
>> nop
>> nop
>> nop
>> +
>> + /* XXX gpio fclk workaround */
>> + ldr r5, cm_fclken_per_val
>> + cmp r5, #0x0
>> + beq skip_per_fclken_restore_2
>> + str r5, [r4]
>> +skip_per_fclken_restore_2:
>> +
>> bl i_dll_wait
>> /* restore regs and return */
>> ldmfd sp!, {r0-r12, pc}
>> @@ -540,5 +608,11 @@ table_entry:
>> .word 0x00000C02
>> cache_pred_disable_mask:
>> .word 0xFFFFE7FB
>> +cm_fclken_per_v:
>> + .word CM_FCLKEN_PER_V
>> +cm_fclken_per_p:
>> + .word CM_FCLKEN_PER_P
>> +cm_fclken_per_val:
>> + .word 0
>> ENTRY(omap34xx_cpu_suspend_sz)
>> .word . - omap34xx_cpu_suspend
>> --
>> 1.5.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe
>> linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
>
--
Jouni Högander
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks
2008-06-26 12:16 ` Högander Jouni
@ 2008-06-26 12:30 ` Rajendra Nayak
2008-06-26 12:40 ` Högander Jouni
0 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2008-06-26 12:30 UTC (permalink / raw)
To: '"Högander" Jouni'; +Cc: linux-omap
> -----Original Message-----
> From: "Högander" Jouni [mailto:jouni.hogander@nokia.com]
> Sent: Thursday, June 26, 2008 5:46 PM
> To: ext Rajendra Nayak
> Cc: linux-omap@vger.kernel.org
> Subject: Re: [PATCH 6/7] 34XX: PM: Workaround for taking care
> of gpio clocks
>
> "ext Rajendra Nayak" <rnayak@ti.com> writes:
>
> >
> >
> >> -----Original Message-----
> >> From: linux-omap-owner@vger.kernel.org
> >> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of
> Jouni Hogander
> >> Sent: Wednesday, June 25, 2008 2:44 PM
> >> To: linux-omap@vger.kernel.org
> >> Subject: [PATCH 6/7] 34XX: PM: Workaround for taking care of
> >> gpio clocks
> >>
> >> In omap3 gpios 2-6 are in per domain. Clocks for these should be
> >> disabled. This patch is needed until gpio driver disables
> gpio clocks.
> >>
> >> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> >> ---
> >> arch/arm/mach-omap2/pm34xx.c | 15 +++++++-
> >> arch/arm/mach-omap2/sleep34xx.S | 74
> >> +++++++++++++++++++++++++++++++++++++++
> >> 2 files changed, 87 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/arch/arm/mach-omap2/pm34xx.c
> >> b/arch/arm/mach-omap2/pm34xx.c
> >> index edde254..9c7b7be 100644
> >> --- a/arch/arm/mach-omap2/pm34xx.c
> >> +++ b/arch/arm/mach-omap2/pm34xx.c
> >> @@ -47,12 +47,19 @@ struct power_state {
> >>
> >> static LIST_HEAD(pwrst_list);
> >>
> >> -void (*_omap_sram_idle)(u32 *addr, int save_state);
> >> +void (*_omap_sram_idle)(u32 *addr, int save_state, int
> >> disable_clocks);
> >>
> >> static void (*saved_idle)(void);
> >>
> >> static struct powerdomain *mpu_pwrdm;
> >>
> >> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> >> + * handles fcks correctly */
> >> +static void gpio_fclk_mask(u32 *fclk)
> >> +{
> >> + *fclk &= ~(0x1f << 13);
> >> +}
> >> +
> >> /* PRCM Interrupt Handler for wakeups */
> >> static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
> >> {
> >> @@ -169,7 +176,7 @@ static void omap_sram_idle(void)
> >>
> >> omap2_gpio_prepare_for_retention();
> >>
> >> - _omap_sram_idle(NULL, save_state);
> >> + _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
> >>
> >> omap2_gpio_resume_after_retention();
> >> }
> >> @@ -197,6 +204,10 @@ static int omap3_fclks_active(void)
> >> CM_FCLKEN);
> >> fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
> >> CM_FCLKEN);
> >> +
> >> + if (clocks_off_while_idle)
> >> + gpio_fclk_mask(&fck_per);
> >> +
> >> if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
> >> fck_cam | fck_per | fck_usbhost)
> >> return 1;
> >> diff --git a/arch/arm/mach-omap2/sleep34xx.S
> >> b/arch/arm/mach-omap2/sleep34xx.S
> >> index ebc7eb3..1f7009a 100644
> >> --- a/arch/arm/mach-omap2/sleep34xx.S
> >> +++ b/arch/arm/mach-omap2/sleep34xx.S
> >> @@ -32,6 +32,8 @@
> >>
> >> #include "prm.h"
> >> #include "sdrc.h"
> >> +#include "cm.h"
> >> +#include "cm-regbits-34xx.h"
> >>
> >> #define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
> >> OMAP3430_PM_PREPWSTST)
> >> @@ -45,6 +47,15 @@
> >> SCRATCHPAD_MEM_OFFS)
> >> #define SDRC_POWER_V
> OMAP34XX_SDRC_REGADDR(SDRC_POWER)
> >>
> >> +/* XXX gpio fclk workaround */
> >> +#define CM_FCLKEN_PER_V
> >> OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD, \
> >> + CM_FCLKEN)
> >> +#define CM_FCLKEN_PER_P io_v2p(CM_FCLKEN_PER_V)
> >> +
> >> +#define GPIO_FCLK_MASK OMAP3430_EN_GPIO6 |
> >> OMAP3430_EN_GPIO5 | \
> >> + OMAP3430_EN_GPIO4 |
> >> OMAP3430_EN_GPIO3 | \
> >> + OMAP3430_EN_GPIO2
> >> +
> >> .text
> >> /* Function call to get the restore pointer for resume from OFF */
> >> ENTRY(get_restore_pointer)
> >> @@ -68,14 +79,41 @@ loop:
> >> /*b loop*/ @Enable to debug by stepping through code
> >> /* r0 contains restore pointer in sdram */
> >> /* r1 contains information about saving context */
> >> + /* r2 contains information whether clocks should be disabled */
> >> ldr r4, sdrc_power @ read the SDRC_POWER register
> >> ldr r5, [r4] @ read the contents of
> >> SDRC_POWER
> >> orr r5, r5, #0x40 @ enable self refresh
> >> on idle req
> >> str r5, [r4] @ write back to
> >> SDRC_POWER register
> >>
> >> + /* XXX gpio fclk workaround */
> >> + /* Check if per fclken needs to be saved */
> >> + cmp r2, #0x0
> >> + beq skip_per_fclken_save
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + /* Save current value of per fclken reg */
> >> + ldr r4, cm_fclken_per_v
> >> + ldr r5, [r4]
> >> + str r5, cm_fclken_per_val
> >> +skip_per_fclken_save:
> >> +
> >
> > Any reason why this is now done in SRAM?
>
> Because of the fact that gpios in per domain are not able to generate
> wakeup/interrupt if per domain is not active. We want to put per
> domain into sleep state as late as possible. IOPAD wakeup starts to
> work only after mpu enters its sleep state.
>
A much easiler way to do this is to put a sleep dep on MPU.
> >
> >> cmp r1, #0x0
> >> /* If context save is required, do that and execute wfi */
> >> bne save_context_wfi
> >
> > In case of OFF mode, clocks would never be disabled.
>
> Isn't it done below. I might be wrong because I haven't been able to
> test this with off mode.
No, it takes a complete different path from save_context_wfi and has a
different exit path as well.
>
> >
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + /* Check if gpio clocks needs to be disabled */
> >> + ldr r5, cm_fclken_per_val
> >> + cmp r5, #0x0
> >> + beq skip_gpio_clk_disable
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + /* Disable gpio clocks */
> >> + ldr r4, cm_fclken_per_v
> >> + bic r5, r5, #GPIO_FCLK_MASK
> >> + str r5, [r4]
> >> +skip_gpio_clk_disable:
> >
> > Even with clocks_off_while_idle set to 1, should'nt gpio
> clocks be cut and restored only
> > when a PER RET/OFF is attemted and not every time omap_sram_idle is
> > called?
>
> Where this would then happen if not in sram? I mean gpio clock control
The previous patches used to do it in per_gpio_clk_disable/enable(), similar to the way
UART clocks are handled. That looked like a better aproach to me.
> is not in current gpio code and adding that into it needs huge
> effort. I'm not sure if it can be even handled there, because of this
> wakeup problem. Basically we have this need to keep per gpios active
> as long as possible, because after disabling their clocks they wont
> generate interrupts/wakeups until mpu is in ret or off mode.
>
> >
> >> +
> >> /* Data memory barrier and Data sync barrier */
> >> mov r1, #0
> >> mcr p15, 0, r1, c7, c10, 4
> >> @@ -93,6 +131,14 @@ loop:
> >> nop
> >> nop
> >> nop
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + ldr r5, cm_fclken_per_val
> >> + cmp r5, #0x0
> >> + beq skip_per_fclken_restore
> >> + str r5, [r4]
> >> +skip_per_fclken_restore:
> >> +
> >> bl i_dll_wait
> >>
> >> ldmfd sp!, {r0-r12, pc} @ restore regs
> >> and return
> >> @@ -483,6 +529,20 @@ finished:
> >> mcr p15, 2, r10, c0, c0, 0
> >> isb
> >> skip_l2_inval:
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + /* Check if gpio clocks needs to be disabled */
> >> + ldr r5, cm_fclken_per_val
> >> + cmp r5, #0x0
> >> + beq skip_gpio_clk_disable_2
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + /* Disable gpio clocks */
> >> + ldr r4, cm_fclken_per_p
> >> + bic r5, r5, #GPIO_FCLK_MASK
> >> + str r5, [r4]
> >> +skip_gpio_clk_disable_2:
> >> +
> >> /* Data memory barrier and Data sync barrier */
> >> mov r1, #0
> >> mcr p15, 0, r1, c7, c10, 4
> >> @@ -499,6 +559,14 @@ skip_l2_inval:
> >> nop
> >> nop
> >> nop
> >> +
> >> + /* XXX gpio fclk workaround */
> >> + ldr r5, cm_fclken_per_val
> >> + cmp r5, #0x0
> >> + beq skip_per_fclken_restore_2
> >> + str r5, [r4]
> >> +skip_per_fclken_restore_2:
> >> +
> >> bl i_dll_wait
> >> /* restore regs and return */
> >> ldmfd sp!, {r0-r12, pc}
> >> @@ -540,5 +608,11 @@ table_entry:
> >> .word 0x00000C02
> >> cache_pred_disable_mask:
> >> .word 0xFFFFE7FB
> >> +cm_fclken_per_v:
> >> + .word CM_FCLKEN_PER_V
> >> +cm_fclken_per_p:
> >> + .word CM_FCLKEN_PER_P
> >> +cm_fclken_per_val:
> >> + .word 0
> >> ENTRY(omap34xx_cpu_suspend_sz)
> >> .word . - omap34xx_cpu_suspend
> >> --
> >> 1.5.5
> >>
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe
> >> linux-omap" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at http://vger.kernel.org/majordomo-info.html
> >>
> >
> >
> >
>
> --
> Jouni Högander
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks
2008-06-26 12:30 ` Rajendra Nayak
@ 2008-06-26 12:40 ` Högander Jouni
0 siblings, 0 replies; 27+ messages in thread
From: Högander Jouni @ 2008-06-26 12:40 UTC (permalink / raw)
To: ext Rajendra Nayak; +Cc: linux-omap
"ext Rajendra Nayak" <rnayak@ti.com> writes:
>
>
>> -----Original Message-----
>> From: "Högander" Jouni [mailto:jouni.hogander@nokia.com]
>> Sent: Thursday, June 26, 2008 5:46 PM
>> To: ext Rajendra Nayak
>> Cc: linux-omap@vger.kernel.org
>> Subject: Re: [PATCH 6/7] 34XX: PM: Workaround for taking care
>> of gpio clocks
>>
>> "ext Rajendra Nayak" <rnayak@ti.com> writes:
>>
>> >
>> >
>> >> -----Original Message-----
>> >> From: linux-omap-owner@vger.kernel.org
>> >> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of
>> Jouni Hogander
>> >> Sent: Wednesday, June 25, 2008 2:44 PM
>> >> To: linux-omap@vger.kernel.org
>> >> Subject: [PATCH 6/7] 34XX: PM: Workaround for taking care of
>> >> gpio clocks
>> >>
>> >> In omap3 gpios 2-6 are in per domain. Clocks for these should be
>> >> disabled. This patch is needed until gpio driver disables
>> gpio clocks.
>> >>
>> >> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
>> >> ---
>> >> arch/arm/mach-omap2/pm34xx.c | 15 +++++++-
>> >> arch/arm/mach-omap2/sleep34xx.S | 74
>> >> +++++++++++++++++++++++++++++++++++++++
>> >> 2 files changed, 87 insertions(+), 2 deletions(-)
>> >>
>> >> diff --git a/arch/arm/mach-omap2/pm34xx.c
>> >> b/arch/arm/mach-omap2/pm34xx.c
>> >> index edde254..9c7b7be 100644
>> >> --- a/arch/arm/mach-omap2/pm34xx.c
>> >> +++ b/arch/arm/mach-omap2/pm34xx.c
>> >> @@ -47,12 +47,19 @@ struct power_state {
>> >>
>> >> static LIST_HEAD(pwrst_list);
>> >>
>> >> -void (*_omap_sram_idle)(u32 *addr, int save_state);
>> >> +void (*_omap_sram_idle)(u32 *addr, int save_state, int
>> >> disable_clocks);
>> >>
>> >> static void (*saved_idle)(void);
>> >>
>> >> static struct powerdomain *mpu_pwrdm;
>> >>
>> >> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
>> >> + * handles fcks correctly */
>> >> +static void gpio_fclk_mask(u32 *fclk)
>> >> +{
>> >> + *fclk &= ~(0x1f << 13);
>> >> +}
>> >> +
>> >> /* PRCM Interrupt Handler for wakeups */
>> >> static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
>> >> {
>> >> @@ -169,7 +176,7 @@ static void omap_sram_idle(void)
>> >>
>> >> omap2_gpio_prepare_for_retention();
>> >>
>> >> - _omap_sram_idle(NULL, save_state);
>> >> + _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
>> >>
>> >> omap2_gpio_resume_after_retention();
>> >> }
>> >> @@ -197,6 +204,10 @@ static int omap3_fclks_active(void)
>> >> CM_FCLKEN);
>> >> fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
>> >> CM_FCLKEN);
>> >> +
>> >> + if (clocks_off_while_idle)
>> >> + gpio_fclk_mask(&fck_per);
>> >> +
>> >> if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
>> >> fck_cam | fck_per | fck_usbhost)
>> >> return 1;
>> >> diff --git a/arch/arm/mach-omap2/sleep34xx.S
>> >> b/arch/arm/mach-omap2/sleep34xx.S
>> >> index ebc7eb3..1f7009a 100644
>> >> --- a/arch/arm/mach-omap2/sleep34xx.S
>> >> +++ b/arch/arm/mach-omap2/sleep34xx.S
>> >> @@ -32,6 +32,8 @@
>> >>
>> >> #include "prm.h"
>> >> #include "sdrc.h"
>> >> +#include "cm.h"
>> >> +#include "cm-regbits-34xx.h"
>> >>
>> >> #define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
>> >> OMAP3430_PM_PREPWSTST)
>> >> @@ -45,6 +47,15 @@
>> >> SCRATCHPAD_MEM_OFFS)
>> >> #define SDRC_POWER_V
>> OMAP34XX_SDRC_REGADDR(SDRC_POWER)
>> >>
>> >> +/* XXX gpio fclk workaround */
>> >> +#define CM_FCLKEN_PER_V
>> >> OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD, \
>> >> + CM_FCLKEN)
>> >> +#define CM_FCLKEN_PER_P io_v2p(CM_FCLKEN_PER_V)
>> >> +
>> >> +#define GPIO_FCLK_MASK OMAP3430_EN_GPIO6 |
>> >> OMAP3430_EN_GPIO5 | \
>> >> + OMAP3430_EN_GPIO4 |
>> >> OMAP3430_EN_GPIO3 | \
>> >> + OMAP3430_EN_GPIO2
>> >> +
>> >> .text
>> >> /* Function call to get the restore pointer for resume from OFF */
>> >> ENTRY(get_restore_pointer)
>> >> @@ -68,14 +79,41 @@ loop:
>> >> /*b loop*/ @Enable to debug by stepping through code
>> >> /* r0 contains restore pointer in sdram */
>> >> /* r1 contains information about saving context */
>> >> + /* r2 contains information whether clocks should be disabled */
>> >> ldr r4, sdrc_power @ read the SDRC_POWER register
>> >> ldr r5, [r4] @ read the contents of
>> >> SDRC_POWER
>> >> orr r5, r5, #0x40 @ enable self refresh
>> >> on idle req
>> >> str r5, [r4] @ write back to
>> >> SDRC_POWER register
>> >>
>> >> + /* XXX gpio fclk workaround */
>> >> + /* Check if per fclken needs to be saved */
>> >> + cmp r2, #0x0
>> >> + beq skip_per_fclken_save
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + /* Save current value of per fclken reg */
>> >> + ldr r4, cm_fclken_per_v
>> >> + ldr r5, [r4]
>> >> + str r5, cm_fclken_per_val
>> >> +skip_per_fclken_save:
>> >> +
>> >
>> > Any reason why this is now done in SRAM?
>>
>> Because of the fact that gpios in per domain are not able to generate
>> wakeup/interrupt if per domain is not active. We want to put per
>> domain into sleep state as late as possible. IOPAD wakeup starts to
>> work only after mpu enters its sleep state.
>>
>
> A much easiler way to do this is to put a sleep dep on MPU.
Yes, I just got this also:) Anyway now we need some mean to define
static sleep/wkdeps.
>
>> >
>> >> cmp r1, #0x0
>> >> /* If context save is required, do that and execute wfi */
>> >> bne save_context_wfi
>> >
>> > In case of OFF mode, clocks would never be disabled.
>>
>> Isn't it done below. I might be wrong because I haven't been able to
>> test this with off mode.
>
> No, it takes a complete different path from save_context_wfi and has a
> different exit path as well.
Ok, this code will be removed anyway so.
>
>>
>> >
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + /* Check if gpio clocks needs to be disabled */
>> >> + ldr r5, cm_fclken_per_val
>> >> + cmp r5, #0x0
>> >> + beq skip_gpio_clk_disable
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + /* Disable gpio clocks */
>> >> + ldr r4, cm_fclken_per_v
>> >> + bic r5, r5, #GPIO_FCLK_MASK
>> >> + str r5, [r4]
>> >> +skip_gpio_clk_disable:
>> >
>> > Even with clocks_off_while_idle set to 1, should'nt gpio
>> clocks be cut and restored only
>> > when a PER RET/OFF is attemted and not every time omap_sram_idle is
>> > called?
>>
>> Where this would then happen if not in sram? I mean gpio clock control
>
> The previous patches used to do it in per_gpio_clk_disable/enable(), similar to the way
> UART clocks are handled. That looked like a better aproach to me.
Yes, I will change it back. As said before we need now some mean to
define static dependencies between domains.
>
>> is not in current gpio code and adding that into it needs huge
>> effort. I'm not sure if it can be even handled there, because of this
>> wakeup problem. Basically we have this need to keep per gpios active
>> as long as possible, because after disabling their clocks they wont
>> generate interrupts/wakeups until mpu is in ret or off mode.
>>
>> >
>> >> +
>> >> /* Data memory barrier and Data sync barrier */
>> >> mov r1, #0
>> >> mcr p15, 0, r1, c7, c10, 4
>> >> @@ -93,6 +131,14 @@ loop:
>> >> nop
>> >> nop
>> >> nop
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + ldr r5, cm_fclken_per_val
>> >> + cmp r5, #0x0
>> >> + beq skip_per_fclken_restore
>> >> + str r5, [r4]
>> >> +skip_per_fclken_restore:
>> >> +
>> >> bl i_dll_wait
>> >>
>> >> ldmfd sp!, {r0-r12, pc} @ restore regs
>> >> and return
>> >> @@ -483,6 +529,20 @@ finished:
>> >> mcr p15, 2, r10, c0, c0, 0
>> >> isb
>> >> skip_l2_inval:
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + /* Check if gpio clocks needs to be disabled */
>> >> + ldr r5, cm_fclken_per_val
>> >> + cmp r5, #0x0
>> >> + beq skip_gpio_clk_disable_2
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + /* Disable gpio clocks */
>> >> + ldr r4, cm_fclken_per_p
>> >> + bic r5, r5, #GPIO_FCLK_MASK
>> >> + str r5, [r4]
>> >> +skip_gpio_clk_disable_2:
>> >> +
>> >> /* Data memory barrier and Data sync barrier */
>> >> mov r1, #0
>> >> mcr p15, 0, r1, c7, c10, 4
>> >> @@ -499,6 +559,14 @@ skip_l2_inval:
>> >> nop
>> >> nop
>> >> nop
>> >> +
>> >> + /* XXX gpio fclk workaround */
>> >> + ldr r5, cm_fclken_per_val
>> >> + cmp r5, #0x0
>> >> + beq skip_per_fclken_restore_2
>> >> + str r5, [r4]
>> >> +skip_per_fclken_restore_2:
>> >> +
>> >> bl i_dll_wait
>> >> /* restore regs and return */
>> >> ldmfd sp!, {r0-r12, pc}
>> >> @@ -540,5 +608,11 @@ table_entry:
>> >> .word 0x00000C02
>> >> cache_pred_disable_mask:
>> >> .word 0xFFFFE7FB
>> >> +cm_fclken_per_v:
>> >> + .word CM_FCLKEN_PER_V
>> >> +cm_fclken_per_p:
>> >> + .word CM_FCLKEN_PER_P
>> >> +cm_fclken_per_val:
>> >> + .word 0
>> >> ENTRY(omap34xx_cpu_suspend_sz)
>> >> .word . - omap34xx_cpu_suspend
>> >> --
>> >> 1.5.5
>> >>
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe
>> >> linux-omap" in
>> >> the body of a message to majordomo@vger.kernel.org
>> >> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> >>
>> >
>> >
>> >
>>
>> --
>> Jouni Högander
>>
>>
>
>
>
--
Jouni Högander
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 7/7] Added sleep support to UART
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
` (5 preceding siblings ...)
2008-06-25 9:13 ` [PATCH 6/7] 34XX: PM: Workaround for taking care of gpio clocks Jouni Hogander
@ 2008-06-25 9:13 ` Jouni Hogander
2008-06-25 11:38 ` [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Rajendra Nayak
7 siblings, 0 replies; 27+ messages in thread
From: Jouni Hogander @ 2008-06-25 9:13 UTC (permalink / raw)
To: linux-omap; +Cc: Tero Kristo
From: Tero Kristo <tero.kristo@nokia.com>
UART usage (e.g. serial console) now denies sleep for 5 seconds. This
makes it possible to use serial console when dynamic idle is
enabled. Write 1 to /sys/power/clocks_off_while_sleep to enable uart
clock disable on idle. Without this omap won't enter retention.
Also moved code from pm-debug.c to serial.c, and made pm24xx.c use
this new implementation.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/pm-debug.c | 132 --------------------------------
arch/arm/mach-omap2/pm.h | 8 --
arch/arm/mach-omap2/pm24xx.c | 57 ++++++++------
arch/arm/mach-omap2/pm34xx.c | 16 ++++-
arch/arm/mach-omap2/serial.c | 148 ++++++++++++++++++++++++++++++++++++
include/asm-arm/arch-omap/common.h | 3 +
6 files changed, 200 insertions(+), 164 deletions(-)
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index a32f11f..61d4501 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -37,138 +37,6 @@
#ifdef CONFIG_PM_DEBUG
int omap2_pm_debug = 0;
-static int serial_console_clock_disabled;
-static int serial_console_uart;
-static unsigned int serial_console_next_disable;
-
-static struct clk *console_iclk, *console_fclk;
-
-static void serial_console_kick(void)
-{
- serial_console_next_disable = omap2_read_32k_sync_counter();
- /* Keep the clocks on for 4 secs */
- serial_console_next_disable += 4 * 32768;
-}
-
-static void serial_wait_tx(void)
-{
- static const unsigned long uart_bases[3] = {
- 0x4806a000, 0x4806c000, 0x4806e000
- };
- unsigned long lsr_reg;
- int looped = 0;
-
- /* Wait for TX FIFO and THR to get empty */
- lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 << 2));
- while ((__raw_readb(lsr_reg) & 0x60) != 0x60)
- looped = 1;
- if (looped)
- serial_console_kick();
-}
-
-u32 omap2_read_32k_sync_counter(void)
-{
- return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010);
-}
-
-void serial_console_fclk_mask(u32 *f1, u32 *f2)
-{
- switch (serial_console_uart) {
- case 1:
- *f1 &= ~(1 << 21);
- break;
- case 2:
- *f1 &= ~(1 << 22);
- break;
- case 3:
- *f2 &= ~(1 << 2);
- break;
- }
-}
-
-void serial_console_sleep(int enable)
-{
- if (console_iclk == NULL || console_fclk == NULL)
- return;
-
- if (enable) {
- BUG_ON(serial_console_clock_disabled);
- if (clk_get_usecount(console_fclk) == 0)
- return;
- if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0)
- return;
- serial_wait_tx();
- clk_disable(console_iclk);
- clk_disable(console_fclk);
- serial_console_clock_disabled = 1;
- } else {
- int serial_wakeup = 0;
- u32 l;
-
- switch (serial_console_uart) {
- case 1:
- l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
- if (l & OMAP24XX_ST_UART1)
- serial_wakeup = 1;
- break;
- case 2:
- l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
- if (l & OMAP24XX_ST_UART2)
- serial_wakeup = 1;
- break;
- case 3:
- l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2);
- if (l & OMAP24XX_ST_UART3)
- serial_wakeup = 1;
- break;
- }
- if (serial_wakeup)
- serial_console_kick();
- if (!serial_console_clock_disabled)
- return;
- clk_enable(console_iclk);
- clk_enable(console_fclk);
- serial_console_clock_disabled = 0;
- }
-}
-
-void pm_init_serial_console(void)
-{
- const struct omap_serial_console_config *conf;
- char name[16];
-
- conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
- struct omap_serial_console_config);
- if (conf == NULL)
- return;
- if (conf->console_uart > 3 || conf->console_uart < 1)
- return;
- serial_console_uart = conf->console_uart;
- sprintf(name, "uart%d_fck", conf->console_uart);
- console_fclk = clk_get(NULL, name);
- if (IS_ERR(console_fclk))
- console_fclk = NULL;
- name[6] = 'i';
- console_iclk = clk_get(NULL, name);
- if (IS_ERR(console_fclk))
- console_iclk = NULL;
- if (console_fclk == NULL || console_iclk == NULL) {
- serial_console_uart = 0;
- return;
- }
- switch (serial_console_uart) {
- case 1:
- prm_set_mod_reg_bits(OMAP24XX_ST_UART1, CORE_MOD, PM_WKEN1);
- break;
- case 2:
- prm_set_mod_reg_bits(OMAP24XX_ST_UART2, CORE_MOD, PM_WKEN1);
- break;
- case 3:
- prm_set_mod_reg_bits(OMAP24XX_ST_UART3, CORE_MOD, OMAP24XX_PM_WKEN2);
- break;
- }
-}
-
#define DUMP_PRM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
regs[reg_count++].val = prm_read_mod_reg(mod, reg)
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 0aeb461..8825339 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -21,18 +21,10 @@ extern unsigned short clocks_off_while_idle;
extern atomic_t sleep_block;
#ifdef CONFIG_PM_DEBUG
-extern u32 omap2_read_32k_sync_counter(void);
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
-extern void serial_console_fclk_mask(u32 *f1, u32 *f2);
-extern void pm_init_serial_console(void);
-extern void serial_console_sleep(int enable);
extern int omap2_pm_debug;
#else
-#define omap2_read_32k_sync_counter() 0;
-#define serial_console_sleep(enable) do; while(0)
-#define pm_init_serial_console() do; while(0)
#define omap2_pm_dump(mode,resume,us) do; while(0)
-#define serial_console_fclk_mask(f1,f2) do; while(0)
#define omap2_pm_debug 0
#endif /* CONFIG_PM_DEBUG */
#endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 69972a2..ad5078e 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -44,6 +44,7 @@
#include <asm/arch/mux.h>
#include <asm/arch/dma.h>
#include <asm/arch/board.h>
+#include <asm/arch/common.h>
#include "prm.h"
#include "prm-regbits-24xx.h"
@@ -73,7 +74,10 @@ static int omap2_fclks_active(void)
f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
- serial_console_fclk_mask(&f1, &f2);
+
+ if (uart_clocks_off_while_sleep)
+ omap_serial_fclk_mask(&f1, &f2);
+
if (f1 | f2)
return 1;
return 0;
@@ -81,7 +85,8 @@ static int omap2_fclks_active(void)
static void omap2_enter_full_retention(void)
{
- u32 l, sleep_time = 0;
+ u32 l = 0;
+ struct timespec sleep_time;
/* There is 1 reference hold for all children of the oscillator
* clock, the following will remove it. If no one else uses the
@@ -111,28 +116,33 @@ static void omap2_enter_full_retention(void)
if (omap2_pm_debug) {
omap2_pm_dump(0, 0, 0);
- sleep_time = omap2_read_32k_sync_counter();
+ getnstimeofday(&sleep_time);
}
+ if (uart_clocks_off_while_sleep)
+ omap_serial_enable_clocks(0);
+
/* One last check for pending IRQs to avoid extra latency due
* to sleeping unnecessarily. */
if (omap_irq_pending())
goto no_sleep;
- serial_console_sleep(1);
/* Jump to SRAM suspend code */
omap2_sram_suspend(OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL));
no_sleep:
- serial_console_sleep(0);
+ omap_serial_check_wakeup();
+ if (uart_clocks_off_while_sleep)
+ omap_serial_enable_clocks(1);
if (omap2_pm_debug) {
- unsigned long long tmp;
- u32 resume_time;
-
- resume_time = omap2_read_32k_sync_counter();
- tmp = resume_time - sleep_time;
- tmp *= 1000000;
- omap2_pm_dump(0, 1, tmp / 32768);
+ struct timespec t;
+ struct timespec ts_delta;
+
+ getnstimeofday(&t);
+ ts_delta = timespec_sub(t, sleep_time);
+ omap2_pm_dump(0, 1,
+ div_s64(timespec_to_ns(&ts_delta),
+ NSEC_PER_USEC));
}
omap2_gpio_resume_after_retention();
@@ -193,7 +203,7 @@ static int omap2_allow_mpu_retention(void)
static void omap2_enter_mpu_retention(void)
{
- u32 sleep_time = 0;
+ struct timespec sleep_time;
int only_idle = 0;
/* Putting MPU into the WFI state while a transfer is active
@@ -222,19 +232,20 @@ static void omap2_enter_mpu_retention(void)
if (omap2_pm_debug) {
omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
- sleep_time = omap2_read_32k_sync_counter();
+ getnstimeofday(&sleep_time);
}
omap2_sram_idle();
if (omap2_pm_debug) {
- unsigned long long tmp;
- u32 resume_time;
-
- resume_time = omap2_read_32k_sync_counter();
- tmp = resume_time - sleep_time;
- tmp *= 1000000;
- omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768);
+ struct timespec t;
+ struct timespec ts_delta;
+
+ getnstimeofday(&t);
+ ts_delta = timespec_sub(t, sleep_time);
+ omap2_pm_dump(only_idle ? 2 : 1, 1,
+ div_s64(timespec_to_ns(&ts_delta),
+ NSEC_PER_USEC));
}
}
@@ -250,6 +261,8 @@ static int omap2_can_sleep(void)
return 0;
if (omap_dma_running())
return 0;
+ if (!omap_serial_can_sleep())
+ return 0;
return 1;
}
@@ -517,8 +530,6 @@ int __init omap2_pm_init(void)
prcm_setup_regs();
- pm_init_serial_console();
-
/* Hack to prevent MPU retention when STI console is enabled. */
{
const struct omap_sti_console_config *sti;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 9c7b7be..6239bb9 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -29,6 +29,7 @@
#include <asm/arch/pm.h>
#include <asm/arch/clockdomain.h>
#include <asm/arch/powerdomain.h>
+#include <asm/arch/common.h>
#include "cm.h"
#include "cm-regbits-34xx.h"
@@ -66,6 +67,9 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
u32 wkst, irqstatus_mpu;
u32 fclk, iclk;
+ /* Check if we woke up to serial console activity */
+ omap_serial_check_wakeup();
+
/* WKUP */
wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
if (wkst) {
@@ -176,8 +180,14 @@ static void omap_sram_idle(void)
omap2_gpio_prepare_for_retention();
+ if (clocks_off_while_idle)
+ omap_serial_enable_clocks(0);
+
_omap_sram_idle(NULL, save_state, clocks_off_while_idle);
+ if (clocks_off_while_idle)
+ omap_serial_enable_clocks(1);
+
omap2_gpio_resume_after_retention();
}
@@ -205,8 +215,10 @@ static int omap3_fclks_active(void)
fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
CM_FCLKEN);
- if (clocks_off_while_idle)
+ if (clocks_off_while_idle) {
gpio_fclk_mask(&fck_per);
+ omap_serial_fclk_mask(&fck_core1, &fck_per);
+ }
if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
fck_cam | fck_per | fck_usbhost)
@@ -222,6 +234,8 @@ static int omap3_can_sleep(void)
return 0;
if (atomic_read(&sleep_block) > 0)
return 0;
+ if (!omap_serial_can_sleep())
+ return 0;
return 1;
}
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index b0fa582..905594a 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -22,9 +22,66 @@
#include <asm/arch/common.h>
#include <asm/arch/board.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/control.h>
+
+#include "prm.h"
+#include "pm.h"
+
+#define SERIAL_AWAKE_TIME 5
static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
+static struct timespec omap_serial_next_sleep;
+
+#ifdef CONFIG_ARCH_OMAP24XX
+static const u32 omap2_uart_wk_st[OMAP_MAX_NR_PORTS] = {
+ OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1),
+ OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1),
+ OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKST2)
+};
+static const u32 omap2_uart_wk_en[OMAP_MAX_NR_PORTS] = {
+ OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+ OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+ OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKEN2),
+};
+static const u32 omap2_uart_wk_bit[OMAP_MAX_NR_PORTS] = {
+ OMAP24XX_ST_UART1, OMAP24XX_ST_UART2, OMAP24XX_ST_UART3
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static const u32 omap3_uart_wk_st[OMAP_MAX_NR_PORTS] = {
+ OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1),
+ OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1),
+ OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKST1)
+};
+static const u32 omap3_uart_wk_en[OMAP_MAX_NR_PORTS] = {
+ OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+ OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+ OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKEN1)
+};
+static const u32 omap3_uart_wk_bit[OMAP_MAX_NR_PORTS] = {
+ OMAP3430_ST_UART1, OMAP3430_ST_UART2, OMAP3430_ST_UART3
+};
+#endif
+
+static const u32 *omap_uart_wk_st;
+static const u32 *omap_uart_wk_en;
+static const u32 *omap_uart_wk_bit;
+
+/* UART padconfig registers, these may differ if non-default padconfig
+ is used */
+#define CONTROL_PADCONF_UART1_RX 0x182
+#define CONTROL_PADCONF_UART2_RX 0x17A
+#define CONTROL_PADCONF_UART3_RX 0x19E
+#define PADCONF_WAKEUP_ST 0x8000
+
+static const u32 omap34xx_uart_padconf[OMAP_MAX_NR_PORTS] = {
+ CONTROL_PADCONF_UART1_RX,
+ CONTROL_PADCONF_UART2_RX,
+ CONTROL_PADCONF_UART3_RX
+};
static struct plat_serial8250_port serial_platform_data[] = {
{
@@ -83,6 +140,13 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
}
+static void omap_serial_kick(void)
+{
+ getnstimeofday(&omap_serial_next_sleep);
+ timespec_add_ns(&omap_serial_next_sleep, (s64)SERIAL_AWAKE_TIME *
+ NSEC_PER_SEC);
+}
+
void omap_serial_enable_clocks(int enable)
{
int i;
@@ -99,6 +163,67 @@ void omap_serial_enable_clocks(int enable)
}
}
+void omap_serial_fclk_mask(u32 *f1, u32 *f2)
+{
+ if (uart_ick[0])
+ *f1 &= ~(1 << uart_fck[0]->enable_bit);
+ if (uart_ick[1])
+ *f1 &= ~(1 << uart_fck[1]->enable_bit);
+ if (uart_ick[2])
+ *f2 &= ~(1 << uart_fck[2]->enable_bit);
+}
+
+void omap_serial_check_wakeup(void)
+{
+ int i;
+
+
+ for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+ if (!uart_ick[i])
+ continue;
+
+ if (cpu_is_omap34xx())
+ if (omap_ctrl_readw(omap34xx_uart_padconf[i]) &
+ PADCONF_WAKEUP_ST) {
+ omap_serial_kick();
+ return;
+ }
+
+ if (__raw_readl(omap_uart_wk_st[i]) &
+ omap_uart_wk_bit[i]) {
+ omap_serial_kick();
+ return;
+ }
+ }
+}
+
+int omap_serial_can_sleep(void)
+{
+ int i;
+ struct timespec t;
+
+ struct plat_serial8250_port *p = serial_platform_data;
+
+ getnstimeofday(&t);
+
+ for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+ if (!uart_ick[i])
+ continue;
+ /* Check if we have data in the transmit buffer */
+ if ((serial_read_reg(p + i, UART_LSR) &
+ (UART_LSR_TEMT|UART_LSR_THRE))
+ != (UART_LSR_TEMT|UART_LSR_THRE)) {
+ omap_serial_kick();
+ return 0;
+ }
+ }
+
+ if (timespec_compare(&t, &omap_serial_next_sleep) < 0)
+ return 0;
+
+ return 1;
+}
+
void __init omap_serial_init(void)
{
int i;
@@ -116,8 +241,25 @@ void __init omap_serial_init(void)
if (info == NULL)
return;
+#ifdef CONFIG_ARCH_OMAP24XX
+ if (cpu_is_omap242x()) {
+ omap_uart_wk_st = omap2_uart_wk_st;
+ omap_uart_wk_en = omap2_uart_wk_en;
+ omap_uart_wk_bit = omap2_uart_wk_bit;
+ }
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx()) {
+ omap_uart_wk_st = omap3_uart_wk_st;
+ omap_uart_wk_en = omap3_uart_wk_en;
+ omap_uart_wk_bit = omap3_uart_wk_bit;
+ }
+#endif
+
for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
struct plat_serial8250_port *p = serial_platform_data + i;
+ u32 v;
if (!(info->enabled_uarts & (1 << i))) {
p->membase = NULL;
@@ -142,7 +284,13 @@ void __init omap_serial_init(void)
clk_enable(uart_fck[i]);
omap_serial_reset(p);
+
+ v = __raw_readl(omap_uart_wk_en[i]);
+ v |= omap_uart_wk_bit[i];
+ __raw_writel(v, omap_uart_wk_en[i]);
}
+
+ omap_serial_kick();
}
static struct platform_device serial_device = {
diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h
index 7a48fc9..5d2033b 100644
--- a/include/asm-arm/arch-omap/common.h
+++ b/include/asm-arm/arch-omap/common.h
@@ -35,6 +35,9 @@ extern void omap_map_common_io(void);
extern struct sys_timer omap_timer;
extern void omap_serial_init(void);
extern void omap_serial_enable_clocks(int enable);
+extern int omap_serial_can_sleep(void);
+extern void omap_serial_fclk_mask(u32 *f1, u32 *f2);
+void omap_serial_check_wakeup(void);
#ifdef CONFIG_I2C_OMAP
extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
struct i2c_board_info const *info,
--
1.5.5
^ permalink raw reply related [flat|nested] 27+ messages in thread* RE: [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd.
2008-06-25 9:11 [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Jouni Hogander
` (6 preceding siblings ...)
2008-06-25 9:13 ` [PATCH 7/7] Added sleep support to UART Jouni Hogander
@ 2008-06-25 11:38 ` Rajendra Nayak
2008-06-25 11:43 ` Högander Jouni
7 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2008-06-25 11:38 UTC (permalink / raw)
To: 'Jouni Hogander', linux-omap
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org
> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Jouni Hogander
> Sent: Wednesday, June 25, 2008 2:42 PM
> To: linux-omap@vger.kernel.org
> Subject: [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to
> retention 3rd.
>
> Hi,
>
> This patch set contains all workarounds that are needed to get omap3
> to retention. Also patch from Tero Kristo to get PM to work if using
> serial console is included in this set. Basically all patches in this
> set should be reverted one by one as correct fixes are implemented and
> applied.
>
> This patch set superseeds earlier version sent 2008-06-17 7:28:35.
>
> To get Omap into retention, this patch set still depends on:
> 1. ARCH: OMAP: MUSB: Do not block sleep (Felipe Balbi)
> 2. ARM: OMAP: SmartReflex driver: enable in
> omap_3430sdp_defconfig (Kalle
> Jokiniemi)
> 3. PRCM: 34XX: Fix wrong shift value used in dpll4_m4x2_ck enable bit
> 4. Patch which removes control of usbhost_sar_fck from clock
> tree (Paul
> Walmsley will send this soon)
I tried these steps on the 3430SDP but could'nt hit retention.
What is the 4th patch mentioned above which Paul is yet to send and
how does not having it prevent retention?
>
> Test:
> 1. Apply dependency patches and workaround set on top of them
>
> 2. Enable disabling/enabling of gpio2-6 and uart clocks on idle:
> $ echo 1 > /sys/power/clocks_off_while_idle
>
> 3. Try out static suspend:
> $ echo mem > /sys/power/state
> Wake up from suspend by entering character to serial console. This
> should print out:
> "Successfully put all powerdomains to target state"
>
> 4. Try out dynamic sleep:
> $ echo 1 > /sys/power/sleep_while_idle
> On Omap3430 SDP board VCORE_EN led can be used as an indicator. If
> it starts to blink after a while then Omap enters retention on
> idle. To make this work also display needs to be blanked.
>
> --
> Jouni Högander
>
> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd.
2008-06-25 11:38 ` [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to retention 3rd Rajendra Nayak
@ 2008-06-25 11:43 ` Högander Jouni
0 siblings, 0 replies; 27+ messages in thread
From: Högander Jouni @ 2008-06-25 11:43 UTC (permalink / raw)
To: ext Rajendra Nayak; +Cc: linux-omap
"ext Rajendra Nayak" <rnayak@ti.com> writes:
>> -----Original Message-----
>> From: linux-omap-owner@vger.kernel.org
>> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Jouni Hogander
>> Sent: Wednesday, June 25, 2008 2:42 PM
>> To: linux-omap@vger.kernel.org
>> Subject: [PATCH 0/7] 34XX: PM: Workarounds to get omap3 to
>> retention 3rd.
>>
>> Hi,
>>
>> This patch set contains all workarounds that are needed to get omap3
>> to retention. Also patch from Tero Kristo to get PM to work if using
>> serial console is included in this set. Basically all patches in this
>> set should be reverted one by one as correct fixes are implemented and
>> applied.
>>
>> This patch set superseeds earlier version sent 2008-06-17 7:28:35.
>>
>> To get Omap into retention, this patch set still depends on:
>> 1. ARCH: OMAP: MUSB: Do not block sleep (Felipe Balbi)
>> 2. ARM: OMAP: SmartReflex driver: enable in
>> omap_3430sdp_defconfig (Kalle
>> Jokiniemi)
>> 3. PRCM: 34XX: Fix wrong shift value used in dpll4_m4x2_ck enable bit
>> 4. Patch which removes control of usbhost_sar_fck from clock
>> tree (Paul
>> Walmsley will send this soon)
>
> I tried these steps on the 3430SDP but could'nt hit retention.
> What is the 4th patch mentioned above which Paul is yet to send and
> how does not having it prevent retention?
You can do something like this while waiting for patches from Paul:
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index b4dceea..8370f8a 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -2237,7 +2237,7 @@ static struct clk usbhost_sar_fck = {
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP34XX_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL),
.enable_bit = OMAP3430ES2_SAVEANDRESTORE_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
+ .flags = CLOCK_IN_OMAP3430ES2 | ALWAYS_ENABLED,
.clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
--
Jouni Högander
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 27+ messages in thread