• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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