blob: 6642bb37594ac7784cd3ef45381e18ce24b64d59 [file] [log] [blame]
Sven Schnelled8129f92011-04-20 09:12:17 +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 "superio/nsc/pc87384/pc87384.h"
30#include "ec/acpi/ec.h"
31#include "southbridge/intel/i82801gx/i82801gx.h"
32
33static void dlpc_write_register(int reg, int value)
34{
35 outb(reg, 0x164e);
36 outb(value, 0x164f);
37}
38
39static u8 dlpc_read_register(int reg)
40{
41 outb(reg, 0x164e);
42 return inb(0x164f);
43}
44
45static void dock_write_register(int reg, int value)
46{
47 outb(reg, 0x2e);
48 outb(value, 0x2f);
49}
50
51static u8 dock_read_register(int reg)
52{
53 outb(reg, 0x2e);
54 return inb(0x2f);
55}
56
57static void dlpc_gpio_set_mode(int port, int mode)
58{
59 dlpc_write_register(0xf0, port);
60 dlpc_write_register(0xf1, mode);
61}
62
63static void dock_gpio_set_mode(int port, int mode, int irq)
64{
65 dock_write_register(0xf0, port);
66 dock_write_register(0xf1, mode);
67 dock_write_register(0xf2, irq);
68}
69
70static void dlpc_gpio_init(void)
71{
72 /* Select GPIO module */
73 dlpc_write_register(0x07, 0x07);
74 /* GPIO Base Address 0x1680 */
75 dlpc_write_register(0x60, 0x16);
76 dlpc_write_register(0x61, 0x80);
77
78 /* Activate GPIO */
79 dlpc_write_register(0x30, 0x01);
80
81 dlpc_gpio_set_mode(0x00, 3);
82 dlpc_gpio_set_mode(0x01, 3);
83 dlpc_gpio_set_mode(0x02, 0);
84 dlpc_gpio_set_mode(0x03, 3);
85 dlpc_gpio_set_mode(0x04, 4);
86 dlpc_gpio_set_mode(0x20, 4);
87 dlpc_gpio_set_mode(0x21, 4);
88 dlpc_gpio_set_mode(0x23, 4);
89}
90
91int dlpc_init(void)
92{
93 int timeout = 1000;
94
95 /* Enable 14.318MHz CLK on CLKIN */
96 dlpc_write_register(0x29, 0xa0);
97 while(!(dlpc_read_register(0x29) & 0x10) && timeout--)
98 udelay(1000);
99
100 if (!timeout)
101 return 1;
102
103 /* Select DLPC module */
104 dlpc_write_register(0x07, 0x19);
105 /* DLPC Base Address 0x164c */
106 dlpc_write_register(0x60, 0x16);
107 dlpc_write_register(0x61, 0x4c);
108 /* Activate DLPC */
109 dlpc_write_register(0x30, 0x01);
110
111 dlpc_gpio_init();
112 return 0;
113}
114
115static int dock_superio_init(void)
116{
117 int timeout = 1000;
118 /* startup 14.318MHz Clock */
119 dock_write_register(0x29, 0xa0);
120 /* wait until clock is settled */
121 while(!(dock_read_register(0x29) & 0x10) && timeout--)
122 udelay(1000);
123
124 if (!timeout)
125 return 1;
126
127 /* set GPIO pins to Serial/Parallel Port
128 * functions
129 */
130 dock_write_register(0x22, 0xeb);
131
132 dock_write_register(0x07, PC87384_GPIO);
133 dock_write_register(0x60, 0x16);
134 dock_write_register(0x61, 0x20);
Sven Schnelle40d99bc2011-07-11 15:22:42 +0200135 /* enable GPIO */
136 dock_write_register(0x30, 0x01);
Sven Schnelled8129f92011-04-20 09:12:17 +0000137
138 dock_gpio_set_mode(0x00, PC87384_GPIO_PIN_DEBOUNCE |
139 PC87384_GPIO_PIN_PULLUP, 0x00);
140
141 dock_gpio_set_mode(0x01, PC87384_GPIO_PIN_TYPE_PUSH_PULL |
142 PC87384_GPIO_PIN_OE, 0x00);
143
144 dock_gpio_set_mode(0x02, PC87384_GPIO_PIN_TYPE_PUSH_PULL |
145 PC87384_GPIO_PIN_OE, 0x00);
146
147 dock_gpio_set_mode(0x03, PC87384_GPIO_PIN_DEBOUNCE |
148 PC87384_GPIO_PIN_PULLUP, 0x00);
149
150 dock_gpio_set_mode(0x04, PC87384_GPIO_PIN_DEBOUNCE |
151 PC87384_GPIO_PIN_PULLUP, 0x00);
152
153 dock_gpio_set_mode(0x05, PC87384_GPIO_PIN_DEBOUNCE |
154 PC87384_GPIO_PIN_PULLUP, 0x00);
155
156 dock_gpio_set_mode(0x06, PC87384_GPIO_PIN_DEBOUNCE |
157 PC87384_GPIO_PIN_PULLUP, 0x00);
158
159 dock_gpio_set_mode(0x07, PC87384_GPIO_PIN_DEBOUNCE |
160 PC87384_GPIO_PIN_PULLUP, 0x00);
161
Sven Schnelled8129f92011-04-20 09:12:17 +0000162
163 /* no GPIO events enabled for PORT0 */
164 outb(0x00, 0x1622);
165 /* clear GPIO events on PORT0 */
166 outb(0xff, 0x1623);
167 outb(0xff, 0x1624);
168 /* no GPIO events enabled for PORT1 */
169 outb(0x00, 0x1626);
170
171 /* clear GPIO events on PORT1*/
172 outb(0xff, 0x1627);
173 outb(0x1F, 0x1628);
Sven Schnelle40d99bc2011-07-11 15:22:42 +0200174 outb(0xfd, 0x1620);
Sven Schnelled8129f92011-04-20 09:12:17 +0000175 return 0;
176}
177
178int dock_connect(void)
179{
180 int timeout = 1000;
181
182 outb(0x07, 0x164c);
183
184 timeout = 1000;
185
186 while(!(inb(0x164c) & 8) && timeout--)
187 udelay(1000);
188
189 if (!timeout) {
190 /* docking failed, disable DLPC switch */
191 outb(0x00, 0x164c);
192 dlpc_write_register(0x30, 0x00);
193 return 1;
194 }
195
196 /* Assert D_PLTRST# */
197 outb(0xfe, 0x1680);
198 udelay(1000);
199 /* Deassert D_PLTRST# */
200 outb(0xff, 0x1680);
201 udelay(10000);
202
203 return dock_superio_init();
204}
205
206void dock_disconnect(void)
207{
208 /* disconnect LPC bus */
209 outb(0x00, 0x164c);
210 /* Assert PLTRST and DLPCPD */
211 outb(0xfc, 0x1680);
212}
213
214int dock_present(void)
215{
216 outb(0x61, 0x15ec);
217 return inb(0x15ee) & 1;
218}
219