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, wuzhangjin@gmail.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 #include "ec_kb3310b.h"
24 
reset_cpu(void)25 static void reset_cpu(void)
26 {
27 	/*
28 	 * reset cpu to full speed, this is needed when enabling cpu frequency
29 	 * scalling
30 	 */
31 	LOONGSON_CHIPCFG0 |= 0x7;
32 }
33 
34 /* reset support for fuloong2f */
35 
fl2f_reboot(void)36 static void fl2f_reboot(void)
37 {
38 	reset_cpu();
39 
40 	/* send a reset signal to south bridge.
41 	 *
42 	 * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset
43 	 * normally with this reset operation and it will not work in PMON, but
44 	 * you can type halt command and then reboot, seems the hardware reset
45 	 * logic not work normally.
46 	 */
47 	{
48 		u32 hi, lo;
49 		_rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
50 		lo |= 0x00000001;
51 		_wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
52 	}
53 }
54 
fl2f_shutdown(void)55 static void fl2f_shutdown(void)
56 {
57 	u32 hi, lo, val;
58 	int gpio_base;
59 
60 	/* get gpio base */
61 	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
62 	gpio_base = lo & 0xff00;
63 
64 	/* make cs5536 gpio13 output enable */
65 	val = inl(gpio_base + GPIOL_OUT_EN);
66 	val &= ~(1 << (16 + 13));
67 	val |= (1 << 13);
68 	outl(val, gpio_base + GPIOL_OUT_EN);
69 	mmiowb();
70 	/* make cs5536 gpio13 output low level voltage. */
71 	val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13));
72 	val |= (1 << (16 + 13));
73 	outl(val, gpio_base + GPIOL_OUT_VAL);
74 	mmiowb();
75 }
76 
77 /* reset support for yeeloong2f and mengloong2f notebook */
78 
ml2f_reboot(void)79 void ml2f_reboot(void)
80 {
81 	reset_cpu();
82 
83 	/* sending an reset signal to EC(embedded controller) */
84 	ec_write(REG_RESET, BIT_RESET_ON);
85 }
86 
87 #define yl2f89_reboot ml2f_reboot
88 
89 /* menglong(7inches) laptop has different shutdown logic from 8.9inches */
90 #define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d
91 #define EC_SHUTDOWN_IO_PORT_LOW	 0xff2e
92 #define EC_SHUTDOWN_IO_PORT_DATA 0xff2f
93 #define REG_SHUTDOWN_HIGH        0xFC
94 #define REG_SHUTDOWN_LOW         0x29
95 #define BIT_SHUTDOWN_ON          (1 << 1)
96 
ml2f_shutdown(void)97 static void ml2f_shutdown(void)
98 {
99 	u8 val;
100 	u64 i;
101 
102 	outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH);
103 	outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW);
104 	mmiowb();
105 	val = inb(EC_SHUTDOWN_IO_PORT_DATA);
106 	outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA);
107 	mmiowb();
108 	/* need enough wait here... how many microseconds needs? */
109 	for (i = 0; i < 0x10000; i++)
110 		delay();
111 	outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA);
112 	mmiowb();
113 }
114 
yl2f89_shutdown(void)115 static void yl2f89_shutdown(void)
116 {
117 	/* cpu-gpio0 output low */
118 	LOONGSON_GPIODATA &= ~0x00000001;
119 	/* cpu-gpio0 as output */
120 	LOONGSON_GPIOIE &= ~0x00000001;
121 }
122 
mach_prepare_reboot(void)123 void mach_prepare_reboot(void)
124 {
125 	switch (mips_machtype) {
126 	case MACH_LEMOTE_FL2F:
127 	case MACH_LEMOTE_NAS:
128 	case MACH_LEMOTE_LL2F:
129 		fl2f_reboot();
130 		break;
131 	case MACH_LEMOTE_ML2F7:
132 		ml2f_reboot();
133 		break;
134 	case MACH_LEMOTE_YL2F89:
135 		yl2f89_reboot();
136 		break;
137 	default:
138 		break;
139 	}
140 }
141 
mach_prepare_shutdown(void)142 void mach_prepare_shutdown(void)
143 {
144 	switch (mips_machtype) {
145 	case MACH_LEMOTE_FL2F:
146 	case MACH_LEMOTE_NAS:
147 	case MACH_LEMOTE_LL2F:
148 		fl2f_shutdown();
149 		break;
150 	case MACH_LEMOTE_ML2F7:
151 		ml2f_shutdown();
152 		break;
153 	case MACH_LEMOTE_YL2F89:
154 		yl2f89_shutdown();
155 		break;
156 	default:
157 		break;
158 	}
159 }
160