blob: eed00a1a26a2bbf3c9d74822ee90640e57895101 [file] [log] [blame]
Sven Schnellefea6bd12011-04-01 07:28:56 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
21
22#include <console/console.h>
23#include <device/device.h>
24#include <arch/io.h>
25#include <boot/tables.h>
26#include <delay.h>
27#include <arch/io.h>
28#include "dock.h"
29#include "southbridge/intel/i82801gx/i82801gx.h"
30#include "superio/nsc/pc87392/pc87392.h"
31
32static void dlpc_write_register(int reg, int value)
33{
34 outb(reg, 0x164e);
35 outb(value, 0x164f);
36}
37
38static u8 dlpc_read_register(int reg)
39{
40 outb(reg, 0x164e);
41 return inb(0x164f);
42}
43
44static void dock_write_register(int reg, int value)
45{
46 outb(reg, 0x2e);
47 outb(value, 0x2f);
48}
49
50static u8 dock_read_register(int reg)
51{
52 outb(reg, 0x2e);
53 return inb(0x2f);
54}
55
56static void dlpc_gpio_set_mode(int port, int mode)
57{
58 dlpc_write_register(0xf0, port);
59 dlpc_write_register(0xf1, mode);
60}
61
62static void dock_gpio_set_mode(int port, int mode, int irq)
63{
64 dock_write_register(0xf0, port);
65 dock_write_register(0xf1, mode);
66 dock_write_register(0xf2, irq);
67}
68
69static void dlpc_gpio_init(void)
70{
71 /* Select GPIO module */
72 dlpc_write_register(0x07, 0x07);
73 /* GPIO Base Address 0x1680 */
74 dlpc_write_register(0x60, 0x16);
75 dlpc_write_register(0x61, 0x80);
76
77 /* Activate GPIO */
78 dlpc_write_register(0x30, 0x01);
79
80 dlpc_gpio_set_mode(0x00, 3);
81 dlpc_gpio_set_mode(0x01, 3);
82 dlpc_gpio_set_mode(0x02, 0);
83 dlpc_gpio_set_mode(0x03, 3);
84 dlpc_gpio_set_mode(0x04, 4);
85 dlpc_gpio_set_mode(0x20, 4);
86 dlpc_gpio_set_mode(0x21, 4);
87 dlpc_gpio_set_mode(0x23, 4);
88}
89
90int dlpc_init(void)
91{
92 int timeout = 1000;
93
94 /* Enable 14.318MHz CLK on CLKIN */
95 dlpc_write_register(0x29, 0xa0);
96 while(!(dlpc_read_register(0x29) & 0x10) && timeout--)
97 udelay(1000);
98
99 if (!timeout)
100 return 1;
101
102 /* Select DLPC module */
103 dlpc_write_register(0x07, 0x19);
104 /* DLPC Base Address 0x164c */
105 dlpc_write_register(0x60, 0x16);
106 dlpc_write_register(0x61, 0x4c);
107 /* Activate DLPC */
108 dlpc_write_register(0x30, 0x01);
109
110 outb(0x07, 0x164c);
111
112 timeout = 1000;
113
114 while(!(inb(0x164c) & 8) && timeout--)
115 udelay(1000);
116
117 if (!timeout) {
118 /* docking failed, disable DLPC switch */
119 outb(0x00, 0x164c);
120 dlpc_write_register(0x30, 0x00);
121 return 1;
122 }
123
124 dlpc_gpio_init();
125
126 return 0;
127}
128
129int dock_connect(void)
130{
131 int timeout = 1000;
132
133 /* Assert D_PLTRST# */
134 outb(0xfe, 0x1680);
Sven Schnelle8d0b86c2011-07-11 18:36:16 +0200135 udelay(100000);
Sven Schnellefea6bd12011-04-01 07:28:56 +0000136 /* Deassert D_PLTRST# */
137 outb(0xff, 0x1680);
138
Sven Schnelle8d0b86c2011-07-11 18:36:16 +0200139 udelay(1000);
140
Sven Schnellefea6bd12011-04-01 07:28:56 +0000141 /* startup 14.318MHz Clock */
142 dock_write_register(0x29, 0x06);
143 /* wait until clock is settled */
144 while(!(dock_read_register(0x29) & 0x08) && timeout--)
145 udelay(1000);
146
147 if (!timeout)
148 return 1;
149
150 /* Pin 6: CLKRUN
151 * Pin 72: #DR1
152 * Pin 19: #SMI
153 * Pin 73: #MTR
154 */
155 dock_write_register(0x24, 0x37);
156
157 /* PNF active HIGH */
158 dock_write_register(0x25, 0xa0);
159
160 /* disable FDC */
161 dock_write_register(0x26, 0x01);
162
163 /* Enable GPIO IRQ to #SMI */
164 dock_write_register(0x28, 0x02);
165
166 /* select GPIO */
167 dock_write_register(0x07, 0x07);
168
169 /* set base address */
170 dock_write_register(0x60, 0x16);
171 dock_write_register(0x61, 0x20);
172
173 /* init GPIO pins */
174 dock_gpio_set_mode(0x00, PC87392_GPIO_PIN_DEBOUNCE |
175 PC87392_GPIO_PIN_PULLUP, 0x00);
176
177 dock_gpio_set_mode(0x01, PC87392_GPIO_PIN_DEBOUNCE |
178 PC87392_GPIO_PIN_PULLUP,
179 PC87392_GPIO_PIN_TRIGGERS_SMI);
180
181 dock_gpio_set_mode(0x02, PC87392_GPIO_PIN_PULLUP, 0x00);
182 dock_gpio_set_mode(0x03, PC87392_GPIO_PIN_PULLUP, 0x00);
183 dock_gpio_set_mode(0x04, PC87392_GPIO_PIN_PULLUP, 0x00);
184 dock_gpio_set_mode(0x05, PC87392_GPIO_PIN_PULLUP, 0x00);
185 dock_gpio_set_mode(0x06, PC87392_GPIO_PIN_PULLUP, 0x00);
186 dock_gpio_set_mode(0x07, PC87392_GPIO_PIN_PULLUP, 0x02);
187
188 dock_gpio_set_mode(0x10, PC87392_GPIO_PIN_DEBOUNCE |
189 PC87392_GPIO_PIN_PULLUP,
190 PC87392_GPIO_PIN_TRIGGERS_SMI);
191
192 dock_gpio_set_mode(0x11, PC87392_GPIO_PIN_PULLUP, 0x00);
193 dock_gpio_set_mode(0x12, PC87392_GPIO_PIN_PULLUP, 0x00);
194 dock_gpio_set_mode(0x13, PC87392_GPIO_PIN_PULLUP, 0x00);
195 dock_gpio_set_mode(0x14, PC87392_GPIO_PIN_PULLUP, 0x00);
196 dock_gpio_set_mode(0x15, PC87392_GPIO_PIN_PULLUP, 0x00);
197 dock_gpio_set_mode(0x16, PC87392_GPIO_PIN_PULLUP |
198 PC87392_GPIO_PIN_OE , 0x00);
199
200 dock_gpio_set_mode(0x17, PC87392_GPIO_PIN_PULLUP, 0x00);
201
202 dock_gpio_set_mode(0x20, PC87392_GPIO_PIN_TYPE_PUSH_PULL |
203 PC87392_GPIO_PIN_OE, 0x00);
204
205 dock_gpio_set_mode(0x21, PC87392_GPIO_PIN_TYPE_PUSH_PULL |
206 PC87392_GPIO_PIN_OE, 0x00);
207
208 dock_gpio_set_mode(0x22, PC87392_GPIO_PIN_PULLUP, 0x00);
209 dock_gpio_set_mode(0x23, PC87392_GPIO_PIN_PULLUP, 0x00);
210 dock_gpio_set_mode(0x24, PC87392_GPIO_PIN_PULLUP, 0x00);
211 dock_gpio_set_mode(0x25, PC87392_GPIO_PIN_PULLUP, 0x00);
212 dock_gpio_set_mode(0x26, PC87392_GPIO_PIN_PULLUP, 0x00);
213 dock_gpio_set_mode(0x27, PC87392_GPIO_PIN_PULLUP, 0x00);
214
215 dock_gpio_set_mode(0x30, PC87392_GPIO_PIN_PULLUP, 0x00);
216 dock_gpio_set_mode(0x31, PC87392_GPIO_PIN_PULLUP, 0x00);
217 dock_gpio_set_mode(0x32, PC87392_GPIO_PIN_PULLUP, 0x00);
218 dock_gpio_set_mode(0x33, PC87392_GPIO_PIN_PULLUP, 0x00);
219 dock_gpio_set_mode(0x34, PC87392_GPIO_PIN_PULLUP, 0x00);
220
221 dock_gpio_set_mode(0x35, PC87392_GPIO_PIN_PULLUP |
222 PC87392_GPIO_PIN_OE, 0x00);
223
224 dock_gpio_set_mode(0x36, PC87392_GPIO_PIN_PULLUP, 0x00);
225 dock_gpio_set_mode(0x37, PC87392_GPIO_PIN_PULLUP, 0x00);
226
227 /* enable GPIO */
228 dock_write_register(0x30, 0x01);
229
230 outb(0x00, 0x1628);
231 outb(0x00, 0x1623);
232 outb(0x82, 0x1622);
233 outb(0xff, 0x1624);
234
235 /* Enable USB and Ultrabay power */
236 outb(0x03, 0x1628);
Sven Schnelle8d0b86c2011-07-11 18:36:16 +0200237
238 dock_write_register(0x07, 0x03);
239 dock_write_register(0x30, 0x01);
240 console_init();
Sven Schnellefea6bd12011-04-01 07:28:56 +0000241 return 0;
242}
243
244void dock_disconnect(void)
245{
Sven Schnelle8d0b86c2011-07-11 18:36:16 +0200246 /* disable Ultrabay and USB Power */
247 outb(0x00, 0x1628);
Sven Schnellefea6bd12011-04-01 07:28:56 +0000248 /* disconnect LPC bus */
249 outb(0x00, 0x164c);
250 /* Assert PLTRST and DLPCPD */
251 outb(0xfc, 0x1680);
252}
253
254int dock_present(void)
255{
256 return !((inb(DEFAULT_GPIOBASE + 0x0c) >> 13) & 1);
257}
Sven Schnelle50270b82011-04-27 19:48:05 +0000258
259int dock_ultrabay_device_present(void)
260{
261 return inb(0x1621) & 0x02 ? 0 : 1;
262}