aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/cpu_setup_pa6t.S44
-rw-r--r--arch/powerpc/kernel/cputable.c4
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile3
-rw-r--r--arch/powerpc/platforms/pasemi/idle.c88
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h7
-rw-r--r--arch/powerpc/platforms/pasemi/powersave.S80
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c2
-rw-r--r--include/asm-powerpc/reg.h1
9 files changed, 228 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index d2ded19e4064..8120d428ebfd 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -17,6 +17,7 @@ obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 18 signal_64.o ptrace32.o \
19 paca.o cpu_setup_ppc970.o \ 19 paca.o cpu_setup_ppc970.o \
20 cpu_setup_pa6t.o \
20 firmware.o sysfs.o nvram_64.o 21 firmware.o sysfs.o nvram_64.o
21obj-$(CONFIG_PPC64) += vdso64/ 22obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 23obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
diff --git a/arch/powerpc/kernel/cpu_setup_pa6t.S b/arch/powerpc/kernel/cpu_setup_pa6t.S
new file mode 100644
index 000000000000..4047be25c4d2
--- /dev/null
+++ b/arch/powerpc/kernel/cpu_setup_pa6t.S
@@ -0,0 +1,44 @@
1/*
2 * Copyright (C) 2006-2007 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <asm/processor.h>
22#include <asm/page.h>
23#include <asm/cputable.h>
24#include <asm/ppc_asm.h>
25#include <asm/asm-offsets.h>
26#include <asm/cache.h>
27
28/* Right now, restore and setup are the same thing */
29_GLOBAL(__restore_cpu_pa6t)
30_GLOBAL(__setup_cpu_pa6t)
31 /* Do nothing if not running in HV mode */
32 mfmsr r0
33 rldicl. r0,r0,4,63
34 beqlr
35
36 mfspr r0,SPRN_HID5
37 ori r0,r0,0x30
38 mtspr SPRN_HID5,r0
39
40 mfspr r0,SPRN_LPCR
41 ori r0,r0,0x7000
42 mtspr SPRN_LPCR,r0
43
44 blr
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 4939b3d56dfb..dd17dffbf058 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -43,6 +43,8 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
43#ifdef CONFIG_PPC64 43#ifdef CONFIG_PPC64
44extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 44extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
45extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); 45extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec);
46extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec);
47extern void __restore_cpu_pa6t(unsigned long offset, struct cpu_spec* spec);
46extern void __restore_cpu_ppc970(void); 48extern void __restore_cpu_ppc970(void);
47#endif /* CONFIG_PPC64 */ 49#endif /* CONFIG_PPC64 */
48 50
@@ -369,6 +371,8 @@ static struct cpu_spec cpu_specs[] = {
369 .dcache_bsize = 64, 371 .dcache_bsize = 64,
370 .num_pmcs = 6, 372 .num_pmcs = 6,
371 .pmc_type = PPC_PMC_PA6T, 373 .pmc_type = PPC_PMC_PA6T,
374 .cpu_setup = __setup_cpu_pa6t,
375 .cpu_restore = __restore_cpu_pa6t,
372 .platform = "pa6t", 376 .platform = "pa6t",
373 }, 377 },
374 { /* default match */ 378 { /* default match */
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
index 1be1a993c5f5..fe4da46074bb 100644
--- a/arch/powerpc/platforms/pasemi/Makefile
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -1 +1,2 @@
1obj-y += setup.o pci.o time.o 1obj-y += setup.o pci.o time.o idle.o powersave.o
2
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c
new file mode 100644
index 000000000000..1ca3ff381591
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/idle.c
@@ -0,0 +1,88 @@
1/*
2 * Copyright (C) 2006-2007 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#undef DEBUG
22
23#include <linux/kernel.h>
24#include <linux/string.h>
25
26#include <asm/machdep.h>
27#include <asm/reg.h>
28
29#include "pasemi.h"
30
31struct sleep_mode {
32 char *name;
33 void (*entry)(void);
34};
35
36static struct sleep_mode modes[] = {
37 { .name = "spin", .entry = &idle_spin },
38 { .name = "doze", .entry = &idle_doze },
39};
40
41static int current_mode = 0;
42
43static int pasemi_system_reset_exception(struct pt_regs *regs)
44{
45 /* If we were woken up from power savings, we need to return
46 * to the calling function, since nip is not saved across
47 * all modes.
48 */
49
50 if (regs->msr & SRR1_WAKEMASK)
51 regs->nip = regs->link;
52
53 switch (regs->msr & SRR1_WAKEMASK) {
54 case SRR1_WAKEEE:
55 do_IRQ(regs);
56 break;
57 case SRR1_WAKEDEC:
58 timer_interrupt(regs);
59 break;
60 default:
61 /* do system reset */
62 return 0;
63 }
64 /* everything handled */
65 regs->msr |= MSR_RI;
66 return 1;
67}
68
69void __init pasemi_idle_init(void)
70{
71 ppc_md.system_reset_exception = pasemi_system_reset_exception;
72 ppc_md.power_save = modes[current_mode].entry;
73 printk(KERN_INFO "Using PA6T idle loop (%s)\n", modes[current_mode].name);
74}
75
76static int __init idle_param(char *p)
77{
78 int i;
79 for (i = 0; i < sizeof(modes)/sizeof(struct sleep_mode); i++) {
80 if (!strcmp(modes[i].name, p)) {
81 current_mode = i;
82 break;
83 }
84 }
85 return 0;
86}
87
88early_param("idle", idle_param);
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
index 51c2a2397ecf..94fd00cc6a10 100644
--- a/arch/powerpc/platforms/pasemi/pasemi.h
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -4,4 +4,11 @@
4extern unsigned long pas_get_boot_time(void); 4extern unsigned long pas_get_boot_time(void);
5extern void pas_pci_init(void); 5extern void pas_pci_init(void);
6 6
7extern void __init pasemi_idle_init(void);
8
9/* Power savings modes, implemented in asm */
10extern void idle_spin(void);
11extern void idle_doze(void);
12
13
7#endif /* _PASEMI_PASEMI_H */ 14#endif /* _PASEMI_PASEMI_H */
diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S
new file mode 100644
index 000000000000..6d0fba6aab17
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/powersave.S
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2006-2007 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <asm/processor.h>
22#include <asm/page.h>
23#include <asm/ppc_asm.h>
24#include <asm/cputable.h>
25#include <asm/cache.h>
26#include <asm/thread_info.h>
27#include <asm/asm-offsets.h>
28
29/* Power savings opcodes since not all binutils have them at this time */
30#define DOZE .long 0x4c000324
31#define NAP .long 0x4c000364
32#define SLEEP .long 0x4c0003a4
33#define RVW .long 0x4c0003e4
34
35/* Common sequence to do before going to any of the
36 * powersavings modes.
37 */
38
39#define PRE_SLEEP_SEQUENCE \
40 std r3,8(r1); \
41 ptesync ; \
42 ld r3,8(r1); \
431: cmpd r3,r3; \
44 bne 1b
45
46_doze:
47 PRE_SLEEP_SEQUENCE
48 DOZE
49 b .
50
51
52_GLOBAL(idle_spin)
53 blr
54
55_GLOBAL(idle_doze)
56 LOAD_REG_ADDR(r3, _doze)
57 b sleep_common
58
59/* Add more modes here later */
60
61sleep_common:
62 mflr r0
63 std r0, 16(r1)
64 stdu r1,-64(r1)
65
66 LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE)
67 mfmsr r4
68 andc r5,r4,r6
69 mtmsrd r5,0
70
71 mtctr r3
72 bctrl
73
74 mtmsrd r4,0
75
76 addi r1,r1,64
77 ld r0,16(r1)
78 mtlr r0
79 blr
80
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 4142873a87ef..f69f5e76618f 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -82,7 +82,7 @@ void __init pas_setup_arch(void)
82 conswitchp = &dummy_con; 82 conswitchp = &dummy_con;
83#endif 83#endif
84 84
85 printk(KERN_DEBUG "Using default idle loop\n"); 85 pasemi_idle_init();
86} 86}
87 87
88/* No legacy IO on our parts */ 88/* No legacy IO on our parts */
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 0279d4ec5211..923df6ceaa5c 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -166,6 +166,7 @@
166#define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ 166#define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */
167#define SPRN_SPURR 0x134 /* Scaled PURR */ 167#define SPRN_SPURR 0x134 /* Scaled PURR */
168#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ 168#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */
169#define SPRN_LPCR 0x13E /* LPAR Control Register */
169#define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ 170#define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */
170#define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ 171#define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */
171#define SPRN_DBAT1L 0x21B /* Data BAT 1 Lower Register */ 172#define SPRN_DBAT1L 0x21B /* Data BAT 1 Lower Register */