* [RFC/PATCH] idle loop changes
@ 2002-07-31 19:32 Tom Rini
2002-07-31 20:25 ` Dan Malek
2002-07-31 21:24 ` Matt Porter
0 siblings, 2 replies; 11+ messages in thread
From: Tom Rini @ 2002-07-31 19:32 UTC (permalink / raw)
To: linuxppc-dev
The following is based on the final patch that Armin posted a short
while back. What this does is allow for the power_save() function to be
overridden, but still provide a 'sane' default. This moves the existing
power_save() function into ppc6xx_idle.c, as after talking with Hollis,
the function won't work as-is on Power3/iSeries (bits have moved or are
non-existant).
I'm not totally sure if it's better to do it this way, or to not provide
a default power_save(), so that if we don't set pm_idle to something, we
just never call power_save() (as opposed to a call, check for a bit &
return). Comments?
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile Wed Jul 31 12:04:53 2002
+++ b/arch/ppc/kernel/Makefile Wed Jul 31 12:04:53 2002
@@ -41,7 +41,7 @@
process.o signal.o ptrace.o align.o \
semaphore.o syscalls.o setup.o \
cputable.o ppc_htab.o
-obj-$(CONFIG_6xx) += l2cr.o
+obj-$(CONFIG_6xx) += l2cr.o ppc6xx_idle.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_PCI) += pci.o
ifneq ($(CONFIG_PPC_ISERIES),y)
diff -Nru a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
--- a/arch/ppc/kernel/idle.c Wed Jul 31 12:04:53 2002
+++ b/arch/ppc/kernel/idle.c Wed Jul 31 12:04:53 2002
@@ -11,6 +11,11 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
+ *
+ * 07/27/02 - Armin & Tom.
+ * added powersave idle loop indirection scheme borrowed from
+ * i386 & arm so other PPC archs can have their own if the
+ * default is not sufficiant.
*/
#include <linux/config.h>
#include <linux/errno.h>
@@ -50,9 +55,9 @@
void zero_paged(void);
void power_save(void);
+void (*pm_idle)(void);
unsigned long zero_paged_on = 0;
-unsigned long powersave_nap = 0;
unsigned long *zero_cache; /* head linked list of pre-zero'd pages */
atomic_t zerototal; /* # pages zero'd over time */
@@ -96,8 +101,12 @@
}
}
#endif
+ void (*idle)(void) = pm_idle;
+ if (!idle)
+ idle = power_save;
+
if (do_power_save && !current->need_resched)
- power_save();
+ idle();
if (current->need_resched) {
run_light_on(1);
@@ -262,17 +271,11 @@
}
#endif /* 0 */
-#define DSSALL .long (0x1f<<26)+(0x10<<21)+(0x336<<1)
-
void power_save(void)
{
- unsigned long hid0;
- int nap = powersave_nap;
-
- /* 7450 has no DOZE mode mode, we return if powersave_nap
- * isn't enabled
- */
- if (!(nap || (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE)))
+ /* Make sure the CPU has the DOZE feature set. */
+ if (!(cur_cpu_spec[smp_processor_id()]->cpu_features
+ & CPU_FTR_CAN_DOZE))
return;
/*
* Disable interrupts to prevent a lost wakeup
@@ -287,28 +290,7 @@
* -- Cort
*/
_nmask_and_or_msr(MSR_EE, 0);
- if (!current->need_resched)
- {
-#ifndef CONFIG_4xx
- __asm__ __volatile__("mfspr %0,1008" : "=r" (hid0) :);
- hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
- hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM;
- __asm__ __volatile__("mtspr 1008,%0" : : "r" (hid0));
- /* Flush pending data streams, consider this instruction
- * exist on all altivec capable CPUs
- */
- __asm__ __volatile__(
- "98: " __stringify(DSSALL) "\n"
- " sync\n"
- "99:\n"
- ".section __ftr_fixup,\"a\"\n"
- " .long %0\n"
- " .long %1\n"
- " .long 98b\n"
- " .long 99b\n"
- ".previous" : : "i" (CPU_FTR_ALTIVEC), "i" (CPU_FTR_ALTIVEC));
-#endif /* !CONFIG_4xx */
-
+ if (!current->need_resched) {
/* set the POW bit in the MSR, and enable interrupts
* so we wake up sometime! */
_nmask_and_or_msr(0, MSR_POW | MSR_EE);
diff -Nru a/arch/ppc/kernel/ppc6xx_idle.c b/arch/ppc/kernel/ppc6xx_idle.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/kernel/ppc6xx_idle.c Wed Jul 31 12:04:53 2002
@@ -0,0 +1,76 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * power_save() rountine for classic PPC CPUs.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/stringify.h>
+
+#include <asm/cputable.h>
+#include <asm/current.h>
+#include <asm/processor.h>
+
+unsigned long powersave_nap = 0;
+
+#define DSSALL .long (0x1f<<26)+(0x10<<21)+(0x336<<1)
+
+void
+ppc6xx_pm_idle(void)
+{
+ unsigned long hid0;
+ int nap = powersave_nap;
+
+ /* 7450 has no DOZE mode mode, we return if powersave_nap
+ * isn't enabled
+ */
+ if (!(nap || (cur_cpu_spec[smp_processor_id()]->cpu_features
+ & CPU_FTR_CAN_DOZE)))
+ return;
+ /*
+ * Disable interrupts to prevent a lost wakeup
+ * when going to sleep. This is necessary even with
+ * RTLinux since we are not guaranteed an interrupt
+ * didn't come in and is waiting for a __sti() before
+ * emulating one. This way, we really do hard disable.
+ *
+ * We assume that we're sti-ed when we come in here. We
+ * are in the idle loop so if we're cli-ed then it's a bug
+ * anyway.
+ * -- Cort
+ */
+ _nmask_and_or_msr(MSR_EE, 0);
+ if (!current->need_resched) {
+ __asm__ __volatile__("mfspr %0,1008":"=r"(hid0):);
+ hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
+ hid0 |= (powersave_nap ? HID0_NAP : HID0_DOZE) | HID0_DPM;
+ __asm__ __volatile__("mtspr 1008,%0"::"r"(hid0));
+ /* Flush pending data streams, consider this instruction
+ * exist on all altivec capable CPUs
+ */
+ __asm__ __volatile__("98: " __stringify(DSSALL) "\n"
+ " sync\n"
+ "99:\n"
+ ".section __ftr_fixup,\"a\"\n"
+ " .long %0\n"
+ " .long %1\n"
+ " .long 98b\n"
+ " .long 99b\n"
+ ".previous"::"i"
+ (CPU_FTR_ALTIVEC), "i"(CPU_FTR_ALTIVEC));
+
+ /* set the POW bit in the MSR, and enable interrupts
+ * so we wake up sometime! */
+ _nmask_and_or_msr(0, MSR_POW | MSR_EE);
+ }
+ _nmask_and_or_msr(0, MSR_EE);
+}
diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c Wed Jul 31 12:04:53 2002
+++ b/arch/ppc/kernel/setup.c Wed Jul 31 12:04:53 2002
@@ -55,6 +55,9 @@
extern void kgdb_map_scc(void);
#endif
+extern void (*pm_idle)(void);
+extern void ppc6xx_pm_idle(void);
+
extern boot_infos_t *boot_infos;
char saved_command_line[512];
extern char cmd_line[512];
@@ -511,6 +514,10 @@
#endif /* CONFIG_CMDLINE */
platform_init(r3, r4, r5, r6, r7);
+
+#ifdef CONFIG_6xx
+ pm_idle = ppc6xx_pm_idle;
+#endif
if (ppc_md.progress)
ppc_md.progress("id mach(): done", 0x200);
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [RFC/PATCH] idle loop changes
2002-07-31 19:32 [RFC/PATCH] idle loop changes Tom Rini
@ 2002-07-31 20:25 ` Dan Malek
2002-07-31 20:38 ` Tom Rini
2002-07-31 21:33 ` Matt Porter
2002-07-31 21:24 ` Matt Porter
1 sibling, 2 replies; 11+ messages in thread
From: Dan Malek @ 2002-07-31 20:25 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-dev
Tom Rini wrote:
> I'm not totally sure if it's better to do it this way, or to not provide
> a default power_save(), so that if we don't set pm_idle to something, we
> just never call power_save() (as opposed to a call, check for a bit &
> return). Comments?
I think whether we force everything to have a power_save() function,
even if it is empty, or initialize a pointer and have an indirect call
doesn't make much difference. What does make a difference, is there could
be power save functions that are unique to a board. Some processors have
power save options that can cause a lower frequency clock to be used which
will affect external devices. In such cases, the devices on a board may
need some adjustment when these power save modes are entered/exited.
Thanks.
-- Dan
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 20:25 ` Dan Malek
@ 2002-07-31 20:38 ` Tom Rini
2002-07-31 20:41 ` Tom Rini
2002-07-31 21:33 ` Matt Porter
1 sibling, 1 reply; 11+ messages in thread
From: Tom Rini @ 2002-07-31 20:38 UTC (permalink / raw)
To: Dan Malek; +Cc: linuxppc-dev
On Wed, Jul 31, 2002 at 04:25:57PM -0400, Dan Malek wrote:
> Tom Rini wrote:
>
> >I'm not totally sure if it's better to do it this way, or to not provide
> >a default power_save(), so that if we don't set pm_idle to something, we
> >just never call power_save() (as opposed to a call, check for a bit &
> >return). Comments?
>
> I think whether we force everything to have a power_save() function,
> even if it is empty, or initialize a pointer and have an indirect call
> doesn't make much difference. What does make a difference, is there could
> be power save functions that are unique to a board. Some processors have
> power save options that can cause a lower frequency clock to be used which
> will affect external devices. In such cases, the devices on a board may
> need some adjustment when these power save modes are entered/exited.
Well, this gets us part of the way there. This allows for the
power_save() functionalility to be totally overridden. For things such
as modifiying the clock, which may require additional device changes, I
think that falls in as another problem, but this should allow for that
problem to be taken care of.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 20:38 ` Tom Rini
@ 2002-07-31 20:41 ` Tom Rini
0 siblings, 0 replies; 11+ messages in thread
From: Tom Rini @ 2002-07-31 20:41 UTC (permalink / raw)
To: Dan Malek; +Cc: linuxppc-dev
On Wed, Jul 31, 2002 at 01:38:10PM -0700, Tom Rini wrote:
>
> On Wed, Jul 31, 2002 at 04:25:57PM -0400, Dan Malek wrote:
> > Tom Rini wrote:
> >
> > >I'm not totally sure if it's better to do it this way, or to not provide
> > >a default power_save(), so that if we don't set pm_idle to something, we
> > >just never call power_save() (as opposed to a call, check for a bit &
> > >return). Comments?
> >
> > I think whether we force everything to have a power_save() function,
> > even if it is empty, or initialize a pointer and have an indirect call
> > doesn't make much difference. What does make a difference, is there could
> > be power save functions that are unique to a board. Some processors have
> > power save options that can cause a lower frequency clock to be used which
> > will affect external devices. In such cases, the devices on a board may
> > need some adjustment when these power save modes are entered/exited.
>
> Well, this gets us part of the way there. This allows for the
> power_save() functionalility to be totally overridden.
And in the case of CONFIG_6xx, if the assignment is moved above the call
to platform_init(), it's even easier to override, if needed, so I've
made that change locally.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 20:25 ` Dan Malek
2002-07-31 20:38 ` Tom Rini
@ 2002-07-31 21:33 ` Matt Porter
2002-07-31 21:29 ` Dan Malek
1 sibling, 1 reply; 11+ messages in thread
From: Matt Porter @ 2002-07-31 21:33 UTC (permalink / raw)
To: Dan Malek; +Cc: Tom Rini, linuxppc-dev
On Wed, Jul 31, 2002 at 04:25:57PM -0400, Dan Malek wrote:
>
> Tom Rini wrote:
>
> > I'm not totally sure if it's better to do it this way, or to not provide
> > a default power_save(), so that if we don't set pm_idle to something, we
> > just never call power_save() (as opposed to a call, check for a bit &
> > return). Comments?
>
> I think whether we force everything to have a power_save() function,
> even if it is empty, or initialize a pointer and have an indirect call
> doesn't make much difference. What does make a difference, is there could
> be power save functions that are unique to a board. Some processors have
> power save options that can cause a lower frequency clock to be used which
> will affect external devices. In such cases, the devices on a board may
> need some adjustment when these power save modes are entered/exited.
So, some new machdep calls that you can populate on a per board basis?
Are you just talking about them being used upon entering/exiting idle?
Regards,
--
Matt Porter
porter@cox.net
This is Linux Country. On a quiet night, you can hear Windows reboot.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 21:33 ` Matt Porter
@ 2002-07-31 21:29 ` Dan Malek
2002-07-31 21:48 ` Mark A. Greer
2002-08-01 0:11 ` Tom Rini
0 siblings, 2 replies; 11+ messages in thread
From: Dan Malek @ 2002-07-31 21:29 UTC (permalink / raw)
To: Matt Porter; +Cc: Tom Rini, linuxppc-dev
Matt Porter wrote:
> So, some new machdep calls that you can populate on a per board basis?
> Are you just talking about them being used upon entering/exiting idle?
I was just thinking the power_save() function could be unique to a
board. It has to be something combined with the power save mode
chosen on the chip, so machdep calls may not be appropriate. We are
using names like ppc6xx_pm_idle, ppc4xx, ppc8xx, when it could be
my_custom_board_pm_idle......Just don't assume one type of chip will
use the same function on different boards. When the idle/power save
function is chosen, it should probably be done during board setup,
not processor set up.
-- Dan
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 21:29 ` Dan Malek
@ 2002-07-31 21:48 ` Mark A. Greer
2002-07-31 22:23 ` Dan Malek
2002-08-01 0:11 ` Tom Rini
1 sibling, 1 reply; 11+ messages in thread
From: Mark A. Greer @ 2002-07-31 21:48 UTC (permalink / raw)
To: Dan Malek; +Cc: Matt Porter, Tom Rini, linuxppc-dev
Dan Malek wrote:
> Matt Porter wrote:
>
> > So, some new machdep calls that you can populate on a per board basis?
> > Are you just talking about them being used upon entering/exiting idle?
>
> I was just thinking the power_save() function could be unique to a
> board. It has to be something combined with the power save mode
> chosen on the chip, so machdep calls may not be appropriate. We are
> using names like ppc6xx_pm_idle, ppc4xx, ppc8xx, when it could be
> my_custom_board_pm_idle......Just don't assume one type of chip will
> use the same function on different boards. When the idle/power save
> function is chosen, it should probably be done during board setup,
> not processor set up.
Why not use keep the ppc6xx_pm_idle, etc. as fallbacks (e.g., nothing
special about your board so use generic 6xx one) and still use machdep
calls so its easy to override in case there is something special you need
to do for your board?
Mark
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 21:48 ` Mark A. Greer
@ 2002-07-31 22:23 ` Dan Malek
0 siblings, 0 replies; 11+ messages in thread
From: Dan Malek @ 2002-07-31 22:23 UTC (permalink / raw)
To: Mark A. Greer; +Cc: Matt Porter, Tom Rini, linuxppc-dev
Mark A. Greer wrote:
> Why not use keep the ppc6xx_pm_idle, etc. as fallbacks (e.g., nothing
> special about your board so use generic 6xx one)
That's fine, except we aren't using machdep calls. The interaction between
the external devices and the processor control may not allow (or we may
not desire) using a "standard" processor function. For example, the MPC8xx
has four powersave modes and four sleep modes. Only one of the modes
is generic and isn't suitable to use if I use one of the other modes that
may require external device management.
My comment was truly simple :-) Just don't assume the processor powersave
modes are suitable for all boards. A board may wish to do something
different, so I suggest keeping the power save function initialization local
to a board rather than processor architecture. Many of them are likely to
be generic and can use the same function, just allow the provision for them
to be different at the board level, that's all.
Thanks.
-- Dan
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 21:29 ` Dan Malek
2002-07-31 21:48 ` Mark A. Greer
@ 2002-08-01 0:11 ` Tom Rini
1 sibling, 0 replies; 11+ messages in thread
From: Tom Rini @ 2002-08-01 0:11 UTC (permalink / raw)
To: Dan Malek; +Cc: Matt Porter, linuxppc-dev
On Wed, Jul 31, 2002 at 05:29:01PM -0400, Dan Malek wrote:
> Matt Porter wrote:
>
> >So, some new machdep calls that you can populate on a per board basis?
> >Are you just talking about them being used upon entering/exiting idle?
>
> I was just thinking the power_save() function could be unique to a
> board. It has to be something combined with the power save mode
> chosen on the chip, so machdep calls may not be appropriate. We are
> using names like ppc6xx_pm_idle, ppc4xx, ppc8xx, when it could be
> my_custom_board_pm_idle......Just don't assume one type of chip will
> use the same function on different boards. When the idle/power save
> function is chosen, it should probably be done during board setup,
> not processor set up.
Right. ppc6xx_pm_idle happens to work in most cases on all of the 6xx
boards, but once this gets in there is nothing stopping fooboard from
overriding this in platform_init().
The whole reason behind these changes is that the current power_save()
is dangerous on 4xx, and with the thought that maybe 8xx (or 405LP)
would need to do something much different.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 19:32 [RFC/PATCH] idle loop changes Tom Rini
2002-07-31 20:25 ` Dan Malek
@ 2002-07-31 21:24 ` Matt Porter
2002-08-01 0:09 ` Tom Rini
1 sibling, 1 reply; 11+ messages in thread
From: Matt Porter @ 2002-07-31 21:24 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-dev
On Wed, Jul 31, 2002 at 12:32:00PM -0700, Tom Rini wrote:
>
> The following is based on the final patch that Armin posted a short
> while back. What this does is allow for the power_save() function to be
> overridden, but still provide a 'sane' default. This moves the existing
> power_save() function into ppc6xx_idle.c, as after talking with Hollis,
> the function won't work as-is on Power3/iSeries (bits have moved or are
> non-existant).
>
> I'm not totally sure if it's better to do it this way, or to not provide
> a default power_save(), so that if we don't set pm_idle to something, we
> just never call power_save() (as opposed to a call, check for a bit &
> return). Comments?
To build it on non-6xx you need to move the powersave_nap declaration
back to idle.c and extern it in ppc6xx_idle.c. It's required by
sysctl. Other than that, this will work.
Regards,
--
Matt Porter
porter@cox.net
This is Linux Country. On a quiet night, you can hear Windows reboot.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC/PATCH] idle loop changes
2002-07-31 21:24 ` Matt Porter
@ 2002-08-01 0:09 ` Tom Rini
0 siblings, 0 replies; 11+ messages in thread
From: Tom Rini @ 2002-08-01 0:09 UTC (permalink / raw)
To: Matt Porter; +Cc: linuxppc-dev
On Wed, Jul 31, 2002 at 02:24:01PM -0700, Matt Porter wrote:
> On Wed, Jul 31, 2002 at 12:32:00PM -0700, Tom Rini wrote:
> >
> > The following is based on the final patch that Armin posted a short
> > while back. What this does is allow for the power_save() function to be
> > overridden, but still provide a 'sane' default. This moves the existing
> > power_save() function into ppc6xx_idle.c, as after talking with Hollis,
> > the function won't work as-is on Power3/iSeries (bits have moved or are
> > non-existant).
> >
> > I'm not totally sure if it's better to do it this way, or to not provide
> > a default power_save(), so that if we don't set pm_idle to something, we
> > just never call power_save() (as opposed to a call, check for a bit &
> > return). Comments?
>
> To build it on non-6xx you need to move the powersave_nap declaration
> back to idle.c and extern it in ppc6xx_idle.c. It's required by
> sysctl. Other than that, this will work.
Bleah. I'm not sure if the sysctl is wrong or not right now. IIRC,
powersave_nap is only actually made use of on pmac, and from what I
remember of talking to Ben, it's only really an option on 6xx anyhow.
But good spotting none the less. :)
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2002-08-01 0:11 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-07-31 19:32 [RFC/PATCH] idle loop changes Tom Rini
2002-07-31 20:25 ` Dan Malek
2002-07-31 20:38 ` Tom Rini
2002-07-31 20:41 ` Tom Rini
2002-07-31 21:33 ` Matt Porter
2002-07-31 21:29 ` Dan Malek
2002-07-31 21:48 ` Mark A. Greer
2002-07-31 22:23 ` Dan Malek
2002-08-01 0:11 ` Tom Rini
2002-07-31 21:24 ` Matt Porter
2002-08-01 0:09 ` Tom Rini
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).