• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <arch/io.h>
6 #include <delay.h>
7 #include "dock.h"
8 #include <southbridge/intel/i82801gx/i82801gx.h>
9 #include <superio/nsc/pc87392/pc87392.h>
10 
dlpc_write_register(int reg,int value)11 static void dlpc_write_register(int reg, int value)
12 {
13 	outb(reg, 0x164e);
14 	outb(value, 0x164f);
15 }
16 
dlpc_read_register(int reg)17 static u8 dlpc_read_register(int reg)
18 {
19 	outb(reg, 0x164e);
20 	return inb(0x164f);
21 }
22 
dock_write_register(int reg,int value)23 static void dock_write_register(int reg, int value)
24 {
25 	outb(reg, 0x2e);
26 	outb(value, 0x2f);
27 }
28 
dock_read_register(int reg)29 static u8 dock_read_register(int reg)
30 {
31 	outb(reg, 0x2e);
32 	return inb(0x2f);
33 }
34 
dlpc_gpio_set_mode(int port,int mode)35 static void dlpc_gpio_set_mode(int port, int mode)
36 {
37 	dlpc_write_register(0xf0, port);
38 	dlpc_write_register(0xf1, mode);
39 }
40 
dock_gpio_set_mode(int port,int mode,int irq)41 static void dock_gpio_set_mode(int port, int mode, int irq)
42 {
43 	dock_write_register(0xf0, port);
44 	dock_write_register(0xf1, mode);
45 	dock_write_register(0xf2, irq);
46 }
47 
dlpc_gpio_init(void)48 static void dlpc_gpio_init(void)
49 {
50 	/* Select GPIO module */
51 	dlpc_write_register(0x07, 0x07);
52 	/* GPIO Base Address 0x1680 */
53 	dlpc_write_register(0x60, 0x16);
54 	dlpc_write_register(0x61, 0x80);
55 
56 	/* Activate GPIO */
57 	dlpc_write_register(0x30, 0x01);
58 
59 	dlpc_gpio_set_mode(0x00, 3);
60 	dlpc_gpio_set_mode(0x01, 3);
61 	dlpc_gpio_set_mode(0x02, 0);
62 	dlpc_gpio_set_mode(0x03, 3);
63 	dlpc_gpio_set_mode(0x04, 4);
64 	dlpc_gpio_set_mode(0x20, 4);
65 	dlpc_gpio_set_mode(0x21, 4);
66 	dlpc_gpio_set_mode(0x23, 4);
67 }
68 
dlpc_init(void)69 int dlpc_init(void)
70 {
71 	int timeout = 1000;
72 
73 	/* Enable 14.318MHz CLK on CLKIN */
74 	dlpc_write_register(0x29, 0xa0);
75 	while (!(dlpc_read_register(0x29) & 0x10) && timeout--)
76 		udelay(1000);
77 
78 	if (!timeout)
79 		return 1;
80 
81 	/* Select DLPC module */
82 	dlpc_write_register(0x07, 0x19);
83 	/* DLPC Base Address 0x164c */
84 	dlpc_write_register(0x60, 0x16);
85 	dlpc_write_register(0x61, 0x4c);
86 	/* Activate DLPC */
87 	dlpc_write_register(0x30, 0x01);
88 
89 	dlpc_gpio_init();
90 
91 	return 0;
92 }
93 
dock_connect(void)94 int dock_connect(void)
95 {
96 	int timeout = 1000;
97 
98 	outb(0x07, 0x164c);
99 
100 	timeout = 1000;
101 
102 	while (!(inb(0x164c) & 8) && timeout--)
103 		udelay(1000);
104 
105 	if (!timeout) {
106 		/* docking failed, disable DLPC switch */
107 		outb(0x00, 0x164c);
108 		dlpc_write_register(0x30, 0x00);
109 		return 1;
110 	}
111 
112 	/* Assert D_PLTRST# */
113 	outb(0xfe, 0x1680);
114 	udelay(100000);
115 	/* Deassert D_PLTRST# */
116 	outb(0xff, 0x1680);
117 
118 	udelay(100000);
119 
120 	/* startup 14.318MHz Clock */
121 	dock_write_register(0x29, 0x06);
122 	/* wait until clock is settled */
123 	timeout = 1000;
124 	while (!(dock_read_register(0x29) & 0x08) && timeout--)
125 		udelay(1000);
126 
127 	if (!timeout)
128 		return 1;
129 
130 	/* Pin  6: CLKRUN
131 	 * Pin 72:  #DR1
132 	 * Pin 19: #SMI
133 	 * Pin 73: #MTR
134 	 */
135 	dock_write_register(0x24, 0x37);
136 
137 	/* PNF active HIGH */
138 	dock_write_register(0x25, 0xa0);
139 
140 	/* disable FDC */
141 	dock_write_register(0x26, 0x01);
142 
143 	/* Enable GPIO IRQ to #SMI */
144 	dock_write_register(0x28, 0x02);
145 
146 	/* select GPIO */
147 	dock_write_register(0x07, 0x07);
148 
149 	/* set base address */
150 	dock_write_register(0x60, 0x16);
151 	dock_write_register(0x61, 0x20);
152 
153 	/* init GPIO pins */
154 	dock_gpio_set_mode(0x00, PC87392_GPIO_PIN_DEBOUNCE |
155 				 PC87392_GPIO_PIN_PULLUP, 0x00);
156 
157 	dock_gpio_set_mode(0x01, PC87392_GPIO_PIN_DEBOUNCE |
158 				 PC87392_GPIO_PIN_PULLUP,
159 				 PC87392_GPIO_PIN_TRIGGERS_SMI);
160 
161 	dock_gpio_set_mode(0x02, PC87392_GPIO_PIN_PULLUP, 0x00);
162 	dock_gpio_set_mode(0x03, PC87392_GPIO_PIN_PULLUP, 0x00);
163 	dock_gpio_set_mode(0x04, PC87392_GPIO_PIN_PULLUP, 0x00);
164 	dock_gpio_set_mode(0x05, PC87392_GPIO_PIN_PULLUP, 0x00);
165 	dock_gpio_set_mode(0x06, PC87392_GPIO_PIN_PULLUP, 0x00);
166 	dock_gpio_set_mode(0x07, PC87392_GPIO_PIN_PULLUP, 0x02);
167 
168 	dock_gpio_set_mode(0x10, PC87392_GPIO_PIN_DEBOUNCE |
169 				 PC87392_GPIO_PIN_PULLUP,
170 				 PC87392_GPIO_PIN_TRIGGERS_SMI);
171 
172 	dock_gpio_set_mode(0x11, PC87392_GPIO_PIN_PULLUP, 0x00);
173 	dock_gpio_set_mode(0x12, PC87392_GPIO_PIN_PULLUP, 0x00);
174 	dock_gpio_set_mode(0x13, PC87392_GPIO_PIN_PULLUP, 0x00);
175 	dock_gpio_set_mode(0x14, PC87392_GPIO_PIN_PULLUP, 0x00);
176 	dock_gpio_set_mode(0x15, PC87392_GPIO_PIN_PULLUP, 0x00);
177 	dock_gpio_set_mode(0x16, PC87392_GPIO_PIN_PULLUP |
178 				 PC87392_GPIO_PIN_OE, 0x00);
179 
180 	dock_gpio_set_mode(0x17, PC87392_GPIO_PIN_PULLUP, 0x00);
181 
182 	dock_gpio_set_mode(0x20, PC87392_GPIO_PIN_TYPE_PUSH_PULL |
183 				 PC87392_GPIO_PIN_OE, 0x00);
184 
185 	dock_gpio_set_mode(0x21, PC87392_GPIO_PIN_TYPE_PUSH_PULL |
186 				 PC87392_GPIO_PIN_OE, 0x00);
187 
188 	dock_gpio_set_mode(0x22, PC87392_GPIO_PIN_PULLUP, 0x00);
189 	dock_gpio_set_mode(0x23, PC87392_GPIO_PIN_PULLUP, 0x00);
190 	dock_gpio_set_mode(0x24, PC87392_GPIO_PIN_PULLUP, 0x00);
191 	dock_gpio_set_mode(0x25, PC87392_GPIO_PIN_PULLUP, 0x00);
192 	dock_gpio_set_mode(0x26, PC87392_GPIO_PIN_PULLUP, 0x00);
193 	dock_gpio_set_mode(0x27, PC87392_GPIO_PIN_PULLUP, 0x00);
194 
195 	dock_gpio_set_mode(0x30, PC87392_GPIO_PIN_PULLUP, 0x00);
196 	dock_gpio_set_mode(0x31, PC87392_GPIO_PIN_PULLUP, 0x00);
197 	dock_gpio_set_mode(0x32, PC87392_GPIO_PIN_PULLUP, 0x00);
198 	dock_gpio_set_mode(0x33, PC87392_GPIO_PIN_PULLUP, 0x00);
199 	dock_gpio_set_mode(0x34, PC87392_GPIO_PIN_PULLUP, 0x00);
200 
201 	dock_gpio_set_mode(0x35, PC87392_GPIO_PIN_PULLUP |
202 				 PC87392_GPIO_PIN_OE, 0x00);
203 
204 	dock_gpio_set_mode(0x36, PC87392_GPIO_PIN_PULLUP, 0x00);
205 	dock_gpio_set_mode(0x37, PC87392_GPIO_PIN_PULLUP, 0x00);
206 
207 	/* enable GPIO */
208 	dock_write_register(0x30, 0x01);
209 
210 	outb(0x00, 0x1628);
211 	outb(0x00, 0x1623);
212 	outb(0x82, 0x1622);
213 	outb(0xff, 0x1624);
214 
215 	/* Enable USB and Ultrabay power */
216 	outb(0x03, 0x1628);
217 
218 	dock_write_register(0x07, 0x03);
219 	dock_write_register(0x30, 0x01);
220 	return 0;
221 }
222 
dock_disconnect(void)223 void dock_disconnect(void)
224 {
225 	printk(BIOS_DEBUG, "%s enter\n", __func__);
226 	/* disconnect LPC bus */
227 	outb(0x00, 0x164c);
228 	udelay(10000);
229 
230 	/* Assert PLTRST and DLPCPD */
231 	outb(0xfc, 0x1680);
232 	udelay(10000);
233 
234 	/* disable Ultrabay and USB Power */
235 	outb(0x00, 0x1628);
236 	udelay(10000);
237 
238 	printk(BIOS_DEBUG, "%s finish\n", __func__);
239 }
240 
dock_present(void)241 int dock_present(void)
242 {
243 	return !((inw(DEFAULT_GPIOBASE + 0x0c) >> 13) & 1);
244 }
245 
dock_ultrabay_device_present(void)246 int dock_ultrabay_device_present(void)
247 {
248 	return inb(0x1621) & 0x02 ? 0 : 1;
249 }
250