diff options
author | Wu Zhangjin <wuzhangjin@gmail.com> | 2009-11-09 11:06:15 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-12-16 20:57:14 -0500 |
commit | 2ee98e0f46a12423d5ecd7da520a1dd94540c37d (patch) | |
tree | 6f0cea5a0b1562d1346b72937edf5e30c17af1ec /arch/mips/loongson | |
parent | 6616db78eecab1236781c546670391e1e5dff256 (diff) |
MIPS: Lemote 2F: Add reset support
Fuloong 2F, Yeeloong 2F and Menglong 2F have different reset / shutdown
logic.
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
Cc: zhangfx@lemote.com
Cc: yanh@lemote.com
Cc: huhb@lemote.com
Cc: Nicholas Mc Guire <hofrat@hofr.at>
Cc: Arnaud Patard <apatard@mandriva.com>
Cc: loongson-dev@googlegroups.com
Cc: linux-mips@linux-mips.org
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/loongson')
-rw-r--r-- | arch/mips/loongson/lemote-2f/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/loongson/lemote-2f/reset.c | 172 |
2 files changed, 173 insertions, 1 deletions
diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile index 2e188974d56b..da543b1b51e1 100644 --- a/arch/mips/loongson/lemote-2f/Makefile +++ b/arch/mips/loongson/lemote-2f/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for lemote loongson2f family machines | 2 | # Makefile for lemote loongson2f family machines |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += irq.o | 5 | obj-y += irq.o reset.o |
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c new file mode 100644 index 000000000000..0458a1c56419 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/reset.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* Board-specific reboot/shutdown routines | ||
2 | * | ||
3 | * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca> | ||
4 | * | ||
5 | * Copyright (C) 2009 Lemote Inc. | ||
6 | * Author: Wu Zhangjin, wuzj@lemote.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/io.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/types.h> | ||
17 | |||
18 | #include <asm/bootinfo.h> | ||
19 | |||
20 | #include <loongson.h> | ||
21 | |||
22 | #include <cs5536/cs5536.h> | ||
23 | |||
24 | static void reset_cpu(void) | ||
25 | { | ||
26 | /* | ||
27 | * reset cpu to full speed, this is needed when enabling cpu frequency | ||
28 | * scalling | ||
29 | */ | ||
30 | LOONGSON_CHIPCFG0 |= 0x7; | ||
31 | } | ||
32 | |||
33 | /* reset support for fuloong2f */ | ||
34 | |||
35 | static void fl2f_reboot(void) | ||
36 | { | ||
37 | reset_cpu(); | ||
38 | |||
39 | /* send a reset signal to south bridge. | ||
40 | * | ||
41 | * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset | ||
42 | * normally with this reset operation and it will not work in PMON, but | ||
43 | * you can type halt command and then reboot, seems the hardware reset | ||
44 | * logic not work normally. | ||
45 | */ | ||
46 | { | ||
47 | u32 hi, lo; | ||
48 | _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); | ||
49 | lo |= 0x00000001; | ||
50 | _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | static void fl2f_shutdown(void) | ||
55 | { | ||
56 | u32 hi, lo, val; | ||
57 | int gpio_base; | ||
58 | |||
59 | /* get gpio base */ | ||
60 | _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); | ||
61 | gpio_base = lo & 0xff00; | ||
62 | |||
63 | /* make cs5536 gpio13 output enable */ | ||
64 | val = inl(gpio_base + GPIOL_OUT_EN); | ||
65 | val &= ~(1 << (16 + 13)); | ||
66 | val |= (1 << 13); | ||
67 | outl(val, gpio_base + GPIOL_OUT_EN); | ||
68 | mmiowb(); | ||
69 | /* make cs5536 gpio13 output low level voltage. */ | ||
70 | val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13)); | ||
71 | val |= (1 << (16 + 13)); | ||
72 | outl(val, gpio_base + GPIOL_OUT_VAL); | ||
73 | mmiowb(); | ||
74 | } | ||
75 | |||
76 | /* reset support for yeeloong2f and mengloong2f notebook */ | ||
77 | |||
78 | /* | ||
79 | * The following registers are determined by the EC index configuration. | ||
80 | * 1. fill the PORT_HIGH as EC register high part. | ||
81 | * 2. fill the PORT_LOW as EC register low part. | ||
82 | * 3. fill the PORT_DATA as EC register write data or get the data from it. | ||
83 | */ | ||
84 | |||
85 | #define EC_IO_PORT_HIGH 0x0381 | ||
86 | #define EC_IO_PORT_LOW 0x0382 | ||
87 | #define EC_IO_PORT_DATA 0x0383 | ||
88 | #define REG_RESET_HIGH 0xF4 /* reset the machine auto-clear : rd/wr */ | ||
89 | #define REG_RESET_LOW 0xEC | ||
90 | #define BIT_RESET_ON (1 << 0) | ||
91 | |||
92 | void ml2f_reboot(void) | ||
93 | { | ||
94 | reset_cpu(); | ||
95 | |||
96 | /* sending an reset signal to EC(embedded controller) */ | ||
97 | outb(REG_RESET_HIGH, EC_IO_PORT_HIGH); | ||
98 | outb(REG_RESET_LOW, EC_IO_PORT_LOW); | ||
99 | mmiowb(); | ||
100 | outb(BIT_RESET_ON, EC_IO_PORT_DATA); | ||
101 | mmiowb(); | ||
102 | } | ||
103 | |||
104 | #define yl2f89_reboot ml2f_reboot | ||
105 | |||
106 | /* menglong(7inches) laptop has different shutdown logic from 8.9inches */ | ||
107 | #define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d | ||
108 | #define EC_SHUTDOWN_IO_PORT_LOW 0xff2e | ||
109 | #define EC_SHUTDOWN_IO_PORT_DATA 0xff2f | ||
110 | #define REG_SHUTDOWN_HIGH 0xFC | ||
111 | #define REG_SHUTDOWN_LOW 0x29 | ||
112 | #define BIT_SHUTDOWN_ON (1 << 1) | ||
113 | |||
114 | static void ml2f_shutdown(void) | ||
115 | { | ||
116 | u8 val; | ||
117 | u64 i; | ||
118 | |||
119 | outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH); | ||
120 | outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW); | ||
121 | mmiowb(); | ||
122 | val = inb(EC_SHUTDOWN_IO_PORT_DATA); | ||
123 | outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA); | ||
124 | mmiowb(); | ||
125 | /* need enough wait here... how many microseconds needs? */ | ||
126 | for (i = 0; i < 0x10000; i++) | ||
127 | delay(); | ||
128 | outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA); | ||
129 | mmiowb(); | ||
130 | } | ||
131 | |||
132 | static void yl2f89_shutdown(void) | ||
133 | { | ||
134 | /* cpu-gpio0 output low */ | ||
135 | LOONGSON_GPIODATA &= ~0x00000001; | ||
136 | /* cpu-gpio0 as output */ | ||
137 | LOONGSON_GPIOIE &= ~0x00000001; | ||
138 | } | ||
139 | |||
140 | void mach_prepare_reboot(void) | ||
141 | { | ||
142 | switch (mips_machtype) { | ||
143 | case MACH_LEMOTE_FL2F: | ||
144 | fl2f_reboot(); | ||
145 | break; | ||
146 | case MACH_LEMOTE_ML2F7: | ||
147 | ml2f_reboot(); | ||
148 | break; | ||
149 | case MACH_LEMOTE_YL2F89: | ||
150 | yl2f89_reboot(); | ||
151 | break; | ||
152 | default: | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | void mach_prepare_shutdown(void) | ||
158 | { | ||
159 | switch (mips_machtype) { | ||
160 | case MACH_LEMOTE_FL2F: | ||
161 | fl2f_shutdown(); | ||
162 | break; | ||
163 | case MACH_LEMOTE_ML2F7: | ||
164 | ml2f_shutdown(); | ||
165 | break; | ||
166 | case MACH_LEMOTE_YL2F89: | ||
167 | yl2f89_shutdown(); | ||
168 | break; | ||
169 | default: | ||
170 | break; | ||
171 | } | ||
172 | } | ||