* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
@ 2010-01-28 22:59 Daniel Walker
2010-01-29 6:49 ` Pavel Machek
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Daniel Walker @ 2010-01-28 22:59 UTC (permalink / raw)
To: linux-arm-kernel
From: Willie Ruan <wruan@quicinc.com>
The application processor in Qualcomm's MSM chips can be powered off
(also called power collapse) during suspend and idle time. L2 cache power
will be collapsed too on current chips. To handle this scenario, we need
to add a function (l2x0_suspend here) to flush L2 cache before the power
loss and another function (l2x0_resume) to restore the cache settings
after the power is restored.
To minimize performance impact these two functions should be called as
close as possible to the point where power is collapsed and restored.
Since it is possible that the power could not be turned off, e.g. due to
a pending interrupt, the parameter 'collapsed' should be used for the
l2x0_resume function to indicate the actual power collapse state.
Signed-off-by: Willie Ruan <wruan@quicinc.com>
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
---
arch/arm/include/asm/hardware/cache-l2x0.h | 3 ++
arch/arm/mm/cache-l2x0.c | 46 ++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index cdb9022..a86b948 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -55,4 +55,7 @@
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
#endif
+extern void l2x0_suspend(void);
+extern void l2x0_resume(int collapsed);
+
#endif
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index cb8fc65..c746878 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -2,6 +2,7 @@
* arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
*
* Copyright (C) 2007 ARM Limited
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -26,6 +27,7 @@
#define CACHE_LINE_SIZE 32
static void __iomem *l2x0_base;
+static uint32_t aux_ctrl_save;
static DEFINE_SPINLOCK(l2x0_lock);
static inline void cache_wait(void __iomem *reg, unsigned long mask)
@@ -54,6 +56,13 @@ static inline void l2x0_inv_all(void)
spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static inline void l2x0_flush_all(void)
+{
+ /* clean and invalidate all ways */
+ sync_writel(0xff, L2X0_CLEAN_INV_WAY, 0xff);
+ cache_sync();
+}
+
static void l2x0_inv_range(unsigned long start, unsigned long end)
{
void __iomem *base = l2x0_base;
@@ -176,3 +185,40 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
printk(KERN_INFO "L2X0 cache controller enabled\n");
}
+
+/*
+ * l2x0_suspend - Suspend L2 cache
+ *
+ * Call this function when L2 cache power will be collapsed (power-off):
+ * 1) during suspend;
+ * 2) during idle.
+ */
+void l2x0_suspend(void)
+{
+ /* Save aux control register value */
+ aux_ctrl_save = readl(l2x0_base + L2X0_AUX_CTRL);
+ /* Flush all cache */
+ l2x0_flush_all();
+ /* Disable the cache */
+ writel(0, l2x0_base + L2X0_CTRL);
+}
+
+/*
+ * l2x0_resume - Resume L2 cache
+ * @collapsed: 1 -- power was collapsed
+ * 0 -- power was not collapsed
+ *
+ * Call this function with the 'collapsed' paramater to tell
+ * whether the power was really collapsed. Cache is still valid
+ * if there was no power loss, thus performance is maintained
+ * because of no need to invalidate the cache.
+ */
+void l2x0_resume(int collapsed)
+{
+ if (collapsed)
+ /* Restore aux control register value */
+ writel(aux_ctrl_save, l2x0_base + L2X0_AUX_CTRL);
+
+ /* Enable the cache */
+ writel(1, l2x0_base + L2X0_CTRL);
+}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 14+ messages in thread* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-28 22:59 [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Daniel Walker
@ 2010-01-29 6:49 ` Pavel Machek
2010-01-29 17:54 ` Ruan, Willie
2010-01-29 11:08 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resumefunctions Catalin Marinas
2010-01-29 14:14 ` Russell King - ARM Linux
2 siblings, 1 reply; 14+ messages in thread
From: Pavel Machek @ 2010-01-29 6:49 UTC (permalink / raw)
To: linux-arm-kernel
On Thu 2010-01-28 14:59:29, Daniel Walker wrote:
> From: Willie Ruan <wruan@quicinc.com>
>
> The application processor in Qualcomm's MSM chips can be powered off
> (also called power collapse) during suspend and idle time. L2 cache power
> will be collapsed too on current chips. To handle this scenario, we need
> to add a function (l2x0_suspend here) to flush L2 cache before the power
> loss and another function (l2x0_resume) to restore the cache settings
> after the power is restored.
So this fixes suspend/resume? Ack...
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resumefunctions
2010-01-28 22:59 [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Daniel Walker
2010-01-29 6:49 ` Pavel Machek
@ 2010-01-29 11:08 ` Catalin Marinas
2010-01-29 17:55 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Ruan, Willie
2010-01-29 14:14 ` Russell King - ARM Linux
2 siblings, 1 reply; 14+ messages in thread
From: Catalin Marinas @ 2010-01-29 11:08 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-01-28 at 22:59 +0000, Daniel Walker wrote:
> diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
> index cb8fc65..c746878 100644
[...]
> +static inline void l2x0_flush_all(void)
> +{
> + /* clean and invalidate all ways */
> + sync_writel(0xff, L2X0_CLEAN_INV_WAY, 0xff);
> + cache_sync();
> +}
Do we need any for of locking around this code (as we do for
l2x0_inv_all) or races are not possible during suspend?
--
Catalin
^ permalink raw reply [flat|nested] 14+ messages in thread* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 11:08 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resumefunctions Catalin Marinas
@ 2010-01-29 17:55 ` Ruan, Willie
2010-01-29 17:59 ` Daniel Walker
0 siblings, 1 reply; 14+ messages in thread
From: Ruan, Willie @ 2010-01-29 17:55 UTC (permalink / raw)
To: linux-arm-kernel
> From: Catalin Marinas [mailto:catalin.marinas at arm.com]
> Sent: Friday, January 29, 2010 3:09 AM
>
> Do we need any for of locking around this code (as we do for
> l2x0_inv_all) or races are not possible during suspend?
Local interrupts have been disabled in suspend_ops->enter and
in arch_idle. Thus, no other locking is necessary.
~Willie
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 17:55 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Ruan, Willie
@ 2010-01-29 17:59 ` Daniel Walker
2010-01-29 18:23 ` Ruan, Willie
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Walker @ 2010-01-29 17:59 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2010-01-29 at 09:55 -0800, Ruan, Willie wrote:
> > From: Catalin Marinas [mailto:catalin.marinas at arm.com]
> > Sent: Friday, January 29, 2010 3:09 AM
> >
> > Do we need any for of locking around this code (as we do for
> > l2x0_inv_all) or races are not possible during suspend?
>
> Local interrupts have been disabled in suspend_ops->enter and
> in arch_idle. Thus, no other locking is necessary.
What if there are multiple cpu's calling cache_sync() at the same time?
Disable interrupt wouldn't prevent it ..
Daniel
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 17:59 ` Daniel Walker
@ 2010-01-29 18:23 ` Ruan, Willie
2010-01-29 18:29 ` Daniel Walker
0 siblings, 1 reply; 14+ messages in thread
From: Ruan, Willie @ 2010-01-29 18:23 UTC (permalink / raw)
To: linux-arm-kernel
> From: Daniel Walker [mailto:dwalker at codeaurora.org]
> Sent: Friday, January 29, 2010 9:59 AM
>
> What if there are multiple cpu's calling cache_sync() at the same time?
> Disable interrupt wouldn't prevent it ..
cache_sync() is calling sync_writel(), which is using spin_lock_irqsave().
So, each call of cache_sync() and sync_writel() is SMP safe individually
in l2x0_flush_all() as in l2x0_inv_all(), unless we need to protect the
two calls together, which seems not necessary to me.
Thanks,
~Willie
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 18:23 ` Ruan, Willie
@ 2010-01-29 18:29 ` Daniel Walker
2010-01-29 19:03 ` Russell King - ARM Linux
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Walker @ 2010-01-29 18:29 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2010-01-29 at 10:23 -0800, Ruan, Willie wrote:
> > From: Daniel Walker [mailto:dwalker at codeaurora.org]
> > Sent: Friday, January 29, 2010 9:59 AM
> >
> > What if there are multiple cpu's calling cache_sync() at the same time?
> > Disable interrupt wouldn't prevent it ..
>
> cache_sync() is calling sync_writel(), which is using spin_lock_irqsave().
> So, each call of cache_sync() and sync_writel() is SMP safe individually
> in l2x0_flush_all() as in l2x0_inv_all(), unless we need to protect the
> two calls together, which seems not necessary to me.
This is the current version,
static inline void cache_wait(void __iomem *reg, unsigned long mask)
{
/* wait for the operation to complete */
while (readl(reg) & mask)
;
}
static inline void cache_sync(void)
{
void __iomem *base = l2x0_base;
writel(0, base + L2X0_CACHE_SYNC);
cache_wait(base + L2X0_CACHE_SYNC, 1);
}
Maybe cache_sync was recently changed to "writel" instead sync_writel()
due it getting called with the lock already held.
Daniel
^ permalink raw reply [flat|nested] 14+ messages in thread* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 18:29 ` Daniel Walker
@ 2010-01-29 19:03 ` Russell King - ARM Linux
2010-01-29 19:12 ` Daniel Walker
0 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-01-29 19:03 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jan 29, 2010 at 10:29:32AM -0800, Daniel Walker wrote:
> On Fri, 2010-01-29 at 10:23 -0800, Ruan, Willie wrote:
> > > From: Daniel Walker [mailto:dwalker at codeaurora.org]
> > > Sent: Friday, January 29, 2010 9:59 AM
> > >
> > > What if there are multiple cpu's calling cache_sync() at the same time?
> > > Disable interrupt wouldn't prevent it ..
> >
> > cache_sync() is calling sync_writel(), which is using spin_lock_irqsave().
> > So, each call of cache_sync() and sync_writel() is SMP safe individually
> > in l2x0_flush_all() as in l2x0_inv_all(), unless we need to protect the
> > two calls together, which seems not necessary to me.
>
> This is the current version,
>
> static inline void cache_wait(void __iomem *reg, unsigned long mask)
> {
> /* wait for the operation to complete */
> while (readl(reg) & mask)
> ;
> }
>
> static inline void cache_sync(void)
> {
> void __iomem *base = l2x0_base;
> writel(0, base + L2X0_CACHE_SYNC);
> cache_wait(base + L2X0_CACHE_SYNC, 1);
> }
>
> Maybe cache_sync was recently changed to "writel" instead sync_writel()
> due it getting called with the lock already held.
It's pointless discussing what the current code does, because that's
not what mainline does _today_ - the locking in this file has
completely changed.
^ permalink raw reply [flat|nested] 14+ messages in thread* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 19:03 ` Russell King - ARM Linux
@ 2010-01-29 19:12 ` Daniel Walker
2010-01-29 19:43 ` Russell King - ARM Linux
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Walker @ 2010-01-29 19:12 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2010-01-29 at 19:03 +0000, Russell King - ARM Linux wrote:
> >
> > Maybe cache_sync was recently changed to "writel" instead sync_writel()
> > due it getting called with the lock already held.
>
> It's pointless discussing what the current code does, because that's
> not what mainline does _today_ - the locking in this file has
> completely changed.
Where is the code we should be looking at (what I quoted is from -next)?
Or is it in -next and we just need to look closer ?
Daniel
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-28 22:59 [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Daniel Walker
2010-01-29 6:49 ` Pavel Machek
2010-01-29 11:08 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resumefunctions Catalin Marinas
@ 2010-01-29 14:14 ` Russell King - ARM Linux
2010-01-29 14:35 ` Daniel Walker
2 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-01-29 14:14 UTC (permalink / raw)
To: linux-arm-kernel
> +static inline void l2x0_flush_all(void)
> +{
> + /* clean and invalidate all ways */
> + sync_writel(0xff, L2X0_CLEAN_INV_WAY, 0xff);
> + cache_sync();
> +}
Note that this patch is out of date; it won't apply to current kernels
and build.
^ permalink raw reply [flat|nested] 14+ messages in thread* [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions
2010-01-29 14:14 ` Russell King - ARM Linux
@ 2010-01-29 14:35 ` Daniel Walker
0 siblings, 0 replies; 14+ messages in thread
From: Daniel Walker @ 2010-01-29 14:35 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2010-01-29 at 14:14 +0000, Russell King - ARM Linux wrote:
> > +static inline void l2x0_flush_all(void)
> > +{
> > + /* clean and invalidate all ways */
> > + sync_writel(0xff, L2X0_CLEAN_INV_WAY, 0xff);
> > + cache_sync();
> > +}
>
> Note that this patch is out of date; it won't apply to current kernels
> and build.
Do you generally prefer patches against current -rc kernels, or against
-next (or you development tree)?
Daniel
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2010-01-29 20:01 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-28 22:59 [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Daniel Walker
2010-01-29 6:49 ` Pavel Machek
2010-01-29 17:54 ` Ruan, Willie
2010-01-29 11:08 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resumefunctions Catalin Marinas
2010-01-29 17:55 ` [RFC PATCH 04/12] arm: mm: cache-l2x0: add l2x0 suspend and resume functions Ruan, Willie
2010-01-29 17:59 ` Daniel Walker
2010-01-29 18:23 ` Ruan, Willie
2010-01-29 18:29 ` Daniel Walker
2010-01-29 19:03 ` Russell King - ARM Linux
2010-01-29 19:12 ` Daniel Walker
2010-01-29 19:43 ` Russell King - ARM Linux
2010-01-29 20:01 ` Daniel Walker
2010-01-29 14:14 ` Russell King - ARM Linux
2010-01-29 14:35 ` Daniel Walker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).