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