• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <console/console.h>
4 #include <delay.h>
5 #include <device/mmio.h>
6 #include <device/pci_def.h>
7 #include <device/pci_ops.h>
8 #include <northbridge/intel/haswell/haswell.h>
9 #include <northbridge/intel/haswell/raminit.h>
10 #include <southbridge/intel/lynxpoint/iobp.h>
11 #include <southbridge/intel/lynxpoint/pch.h>
12 #include <timer.h>
13 #include <types.h>
14 
is_usbr_enabled(void)15 static unsigned int is_usbr_enabled(void)
16 {
17 	return !!(pci_read_config32(PCH_XHCI_DEV, XHCI_USB3FUS) & BIT(5));
18 }
19 
20 static char *const xhci_bar = (char *)PCH_XHCI_TEMP_BAR0;
21 
ehci_hcs_init(const pci_devfn_t dev,const uintptr_t ehci_bar)22 static void ehci_hcs_init(const pci_devfn_t dev, const uintptr_t ehci_bar)
23 {
24 	pci_write_config32(dev, PCI_BASE_ADDRESS_0, ehci_bar);
25 
26 	/** FIXME: Determine whether Bus Master is required (or clean it up afterwards) **/
27 	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
28 
29 	char *const mem_bar = (char *)ehci_bar;
30 
31 	/**
32 	 * Shared EHCI/XHCI ports w/a.
33 	 * This step is required when some of the ports are routed to EHCI
34 	 * and other ports are routed XHCI at the same time.
35 	 *
36 	 * FIXME: Under which conditions should this be done?
37 	 */
38 	pci_and_config16(dev, 0x78, ~0x03);
39 
40 	/* Skip reset if usbdebug is enabled */
41 	if (!CONFIG(USBDEBUG_IN_PRE_RAM))
42 		setbits32(mem_bar + EHCI_USB_CMD, EHCI_USB_CMD_HCRESET);
43 
44 	/* 2: Configure number of controllers and ports */
45 	pci_or_config16(dev, EHCI_ACCESS_CNTL, ACCESS_CNTL_ENABLE);
46 	clrsetbits32(mem_bar + EHCI_HCS_PARAMS, 0xf << 12, 0);
47 	clrsetbits32(mem_bar + EHCI_HCS_PARAMS, 0xf <<  0, 2 + is_usbr_enabled());
48 	pci_and_config16(dev, EHCI_ACCESS_CNTL, ~ACCESS_CNTL_ENABLE);
49 
50 	pci_or_config16(dev, 0x78, BIT(2));
51 	pci_or_config16(dev, 0x7c, BIT(14) | BIT(7));
52 	pci_update_config32(dev, 0x8c, ~(0xf << 8), (4 << 8));
53 	pci_update_config32(dev, 0x8c, ~BIT(26), BIT(17));
54 }
55 
physical_port_count(void)56 static inline unsigned int physical_port_count(void)
57 {
58 	return MAX_USB2_PORTS;
59 }
60 
hs_port_count(void)61 static unsigned int hs_port_count(void)
62 {
63 	/** TODO: Apparently, WPT-LP has 10 USB2 ports **/
64 	if (CONFIG(INTEL_LYNXPOINT_LP))
65 		return 8;
66 
67 	switch ((pci_read_config32(PCH_XHCI_DEV, XHCI_USB3FUS) >> 1) & 3) {
68 	case 3:
69 		return 8;
70 	case 2:
71 		return 10;
72 	case 1:
73 		return 12;
74 	case 0:
75 	default:
76 		return 14;
77 	}
78 }
79 
ss_port_count(void)80 static unsigned int ss_port_count(void)
81 {
82 	if (CONFIG(INTEL_LYNXPOINT_LP))
83 		return 4;
84 
85 	switch ((pci_read_config32(PCH_XHCI_DEV, XHCI_USB3FUS) >> 3) & 3) {
86 	case 3:
87 		return 0;
88 	case 2:
89 		return 2;
90 	case 1:
91 		return 4;
92 	case 0:
93 	default:
94 		return 6;
95 	}
96 }
97 
common_ehci_hcs_init(void)98 static void common_ehci_hcs_init(void)
99 {
100 	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP);
101 
102 	ehci_hcs_init(PCH_EHCI1_DEV, PCH_EHCI1_TEMP_BAR0);
103 	if (!is_lp)
104 		ehci_hcs_init(PCH_EHCI2_DEV, PCH_EHCI2_TEMP_BAR0);
105 
106 	pch_iobp_update(0xe5007f04, 0, 0x00004481);
107 
108 	for (unsigned int port = 0; port < physical_port_count(); port++)
109 		pch_iobp_update(0xe500400f + port * 0x100, ~(1 << 0), 0 << 0);
110 
111 	pch_iobp_update(0xe5007f14, ~(3 << 19), (3 << 19));
112 
113 	if (is_lp)
114 		pch_iobp_update(0xe5007f02, ~(3 << 22), (0 << 22));
115 }
116 
xhci_open_memory_space(void)117 static void xhci_open_memory_space(void)
118 {
119 	/** FIXME: Determine whether Bus Master is required (or clean it up afterwards) **/
120 	pci_write_config32(PCH_XHCI_DEV, PCI_BASE_ADDRESS_0, (uintptr_t)xhci_bar);
121 	pci_or_config16(PCH_XHCI_DEV, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
122 }
123 
xhci_close_memory_space(void)124 static void xhci_close_memory_space(void)
125 {
126 	pci_and_config16(PCH_XHCI_DEV, PCI_COMMAND, ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY));
127 	pci_write_config32(PCH_XHCI_DEV, PCI_BASE_ADDRESS_0, 0);
128 }
129 
common_xhci_hc_init(void)130 static void common_xhci_hc_init(void)
131 {
132 	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP);
133 
134 	if (!is_lp) {
135 		const unsigned int max_ports = 15 + ss_port_count();
136 		clrsetbits32(xhci_bar + XHCI_HCS_PARAMS_1, 0xf << 28, max_ports << 28);
137 	}
138 
139 	clrsetbits32(xhci_bar + XHCI_HCS_PARAMS_3, 0xffff << 16 | 0xff, 0x200 << 16 | 0x0a);
140 	clrsetbits32(xhci_bar + XHCI_HCC_PARAMS, BIT(5), BIT(10) | BIT(9));
141 
142 	if (!is_lp)
143 		clrsetbits32(xhci_bar + 0x8008, BIT(19), 0);
144 
145 	if (is_lp)
146 		clrsetbits32(xhci_bar + 0x8058, BIT(8), BIT(16));
147 	else
148 		clrsetbits32(xhci_bar + 0x8058, BIT(8), BIT(16) | BIT(20));
149 
150 	clrsetbits32(xhci_bar + 0x8060, 0, BIT(25) | BIT(18));
151 	clrsetbits32(xhci_bar + 0x8090, 0, BIT(14) | BIT(8));
152 	clrsetbits32(xhci_bar + 0x8094, 0, BIT(23) | BIT(21) | BIT(14));
153 	clrsetbits32(xhci_bar + 0x80e0, BIT(16), BIT(6));
154 	clrsetbits32(xhci_bar + 0x80ec, (7 << 12) | (7 << 9), (0 << 12) | (6 << 9));
155 	clrsetbits32(xhci_bar + 0x80f0, BIT(20), 0);
156 
157 	if (is_lp)
158 		clrsetbits32(xhci_bar + 0x80fc, 0, BIT(25));
159 
160 	if (is_lp)
161 		clrsetbits32(xhci_bar + 0x8110, BIT(8) | BIT(2), BIT(20) | BIT(11));
162 	else
163 		clrsetbits32(xhci_bar + 0x8110, BIT(2), BIT(20) | BIT(11));
164 
165 	if (is_lp)
166 		write32(xhci_bar + 0x8140, 0xff00f03c);
167 	else
168 		write32(xhci_bar + 0x8140, 0xff03c132);
169 
170 	if (is_lp)
171 		clrsetbits32(xhci_bar + 0x8154, BIT(21), BIT(13));
172 	else
173 		clrsetbits32(xhci_bar + 0x8154, BIT(21) | BIT(13), 0);
174 
175 	clrsetbits32(xhci_bar + 0x8154, BIT(3), 0);
176 
177 	if (is_lp) {
178 		clrsetbits32(xhci_bar + 0x8164, 0, BIT(1) | BIT(0));
179 		write32(xhci_bar + 0x8174, 0x01400c0a);
180 		write32(xhci_bar + 0x817c, 0x033200a3);
181 		write32(xhci_bar + 0x8180, 0x00cb0028);
182 		write32(xhci_bar + 0x8184, 0x0064001e);
183 	}
184 
185 	/*
186 	 * Note: Register at offset 0x44 is 32-bit, but bit 31 is write-once.
187 	 * We use these weird partial accesses here to avoid locking bit 31.
188 	 */
189 	pci_or_config16(PCH_XHCI_DEV, 0x44, BIT(15) | BIT(14) | BIT(10) | BIT(0));
190 	pci_or_config8(PCH_XHCI_DEV, 0x44 + 2, 0x0f);
191 
192 	/* LPT-LP >= B0 */
193 	if (is_lp)
194 		clrsetbits32(xhci_bar + 0x8188, 0, BIT(26) | BIT(24));
195 
196 	/* LPT-H >= C0 */
197 	if (!is_lp)
198 		clrsetbits32(xhci_bar + 0x8188, 0, BIT(24));
199 }
200 
is_mem_sr(void)201 static inline bool is_mem_sr(void)
202 {
203 	return pci_read_config16(PCH_LPC_DEV, GEN_PMCON_2) & GEN_PMCON_2_MEM_SR;
204 }
205 
should_restore_xhci_smart_auto(void)206 static bool should_restore_xhci_smart_auto(void)
207 {
208 	if (!is_mem_sr())
209 		return false;
210 
211 	return pci_read_config32(PCH_LPC_DEV, PMIR) & PMIR_XHCI_SMART_AUTO;
212 }
213 
214 enum usb_port_route {
215 	ROUTE_TO_EHCI,
216 	ROUTE_TO_XHCI,
217 };
218 
219 /* Returns whether port reset was successful */
reset_usb2_ports(const unsigned int ehci_ports)220 static bool reset_usb2_ports(const unsigned int ehci_ports)
221 {
222 	for (unsigned int port = 0; port < ehci_ports; port++) {
223 		/* Initiate port reset for all USB2 ports */
224 		clrsetbits32(
225 			xhci_bar + XHCI_USB2_PORTSC(port),
226 			XHCI_USB2_PORTSC_PED,
227 			XHCI_USB2_PORTSC_PR);
228 	}
229 	/* Poll for port reset bit to be cleared or time out at 100ms */
230 	struct stopwatch timer;
231 	stopwatch_init_msecs_expire(&timer, 100);
232 	uint32_t reg32;
233 	do {
234 		reg32 = 0;
235 		for (unsigned int port = 0; port < ehci_ports; port++)
236 			reg32 |= read32(xhci_bar + XHCI_USB2_PORTSC(port));
237 
238 		reg32 &= XHCI_USB2_PORTSC_PR;
239 		if (!reg32) {
240 			const long elapsed_time = stopwatch_duration_usecs(&timer);
241 			printk(BIOS_DEBUG, "%s: took %lu usecs\n", __func__, elapsed_time);
242 			return true;
243 		}
244 		/* Reference code has a 10 ms delay here, but a smaller delay works too */
245 		udelay(100);
246 	} while (!stopwatch_expired(&timer));
247 	printk(BIOS_ERR, "%s: timed out\n", __func__);
248 	return !reg32;
249 }
250 
251 /* Returns whether warm reset was successful */
warm_reset_usb3_ports(const unsigned int xhci_ports)252 static bool warm_reset_usb3_ports(const unsigned int xhci_ports)
253 {
254 	for (unsigned int port = 0; port < xhci_ports; port++) {
255 		/* Initiate warm reset for all USB3 ports */
256 		clrsetbits32(
257 			xhci_bar + XHCI_USB3_PORTSC(port),
258 			XHCI_USB3_PORTSC_PED,
259 			XHCI_USB3_PORTSC_WPR);
260 	}
261 	/* Poll for port reset bit to be cleared or time out at 100ms */
262 	struct stopwatch timer;
263 	stopwatch_init_msecs_expire(&timer, 100);
264 	uint32_t reg32;
265 	do {
266 		reg32 = 0;
267 		for (unsigned int port = 0; port < xhci_ports; port++)
268 			reg32 |= read32(xhci_bar + XHCI_USB3_PORTSC(port));
269 
270 		reg32 &= XHCI_USB3_PORTSC_PR;
271 		if (!reg32) {
272 			const long elapsed_time = stopwatch_duration_usecs(&timer);
273 			printk(BIOS_DEBUG, "%s: took %lu usecs\n", __func__, elapsed_time);
274 			return true;
275 		}
276 		/* Reference code has a 10 ms delay here, but a smaller delay works too */
277 		udelay(100);
278 	} while (!stopwatch_expired(&timer));
279 	printk(BIOS_ERR, "%s: timed out\n", __func__);
280 	return !reg32;
281 }
282 
perform_xhci_ehci_switching_flow(const enum usb_port_route usb_route)283 static void perform_xhci_ehci_switching_flow(const enum usb_port_route usb_route)
284 {
285 	const pci_devfn_t dev = PCH_XHCI_DEV;
286 
287 	const unsigned int ehci_ports = hs_port_count() + is_usbr_enabled();
288 	const unsigned int xhci_ports = ss_port_count();
289 
290 	const uint32_t ehci_mask = BIT(ehci_ports) - 1;
291 	const uint32_t xhci_mask = BIT(xhci_ports) - 1;
292 
293 	/** TODO: Handle USBr port? How, though? **/
294 	pci_update_config32(dev, XHCI_USB2PRM, ~XHCI_USB2PR_HCSEL, ehci_mask);
295 	pci_update_config32(dev, XHCI_USB3PRM, ~XHCI_USB3PR_SSEN,  xhci_mask);
296 
297 	/*
298 	 * Workaround for USB2PR / USB3PR value not surviving warm reset.
299 	 * Restore USB Port Routing registers if OS HC Switch driver has been executed.
300 	 */
301 	if (should_restore_xhci_smart_auto()) {
302 		/** FIXME: Derive values from mainboard code instead? **/
303 		pci_update_config32(dev, XHCI_USB2PR, ~XHCI_USB2PR_HCSEL, ehci_mask);
304 		pci_update_config32(dev, XHCI_USB3PR, ~XHCI_USB3PR_SSEN,  xhci_mask);
305 	}
306 
307 	/* Later stages shouldn't need the value of this bit */
308 	pci_and_config32(PCH_LPC_DEV, PMIR, ~PMIR_XHCI_SMART_AUTO);
309 
310 	/**
311 	 * FIXME: Things here depend on the chosen routing mode.
312 	 *        For now, implement both functions.
313 	 */
314 
315 	/* Route to EHCI if xHCI disabled or auto mode */
316 	if (usb_route == ROUTE_TO_EHCI) {
317 		if (!reset_usb2_ports(ehci_ports))
318 			printk(BIOS_ERR, "USB2 port reset timed out\n");
319 
320 		pci_and_config32(dev, XHCI_USB2PR, ~XHCI_USB2PR_HCSEL);
321 
322 		for (unsigned int port = 0; port < ehci_ports; port++) {
323 			clrsetbits32(
324 				xhci_bar + XHCI_USB2_PORTSC(port),
325 				XHCI_USB2_PORTSC_PED,
326 				XHCI_USB2_PORTSC_CHST);
327 		}
328 
329 		if (!warm_reset_usb3_ports(xhci_ports))
330 			printk(BIOS_ERR, "USB3 warm reset timed out\n");
331 
332 		/* FIXME: BWG says this should be inside the warm reset function */
333 		pci_and_config32(dev, XHCI_USB3PR, ~XHCI_USB3PR_SSEN);
334 
335 		for (unsigned int port = 0; port < ehci_ports; port++) {
336 			clrsetbits32(
337 				xhci_bar + XHCI_USB3_PORTSC(port),
338 				XHCI_USB3_PORTSC_PED,
339 				XHCI_USB3_PORTSC_CHST);
340 		}
341 
342 		setbits32(xhci_bar + XHCI_USBCMD, BIT(0));
343 		clrbits32(xhci_bar + XHCI_USBCMD, BIT(0));
344 	}
345 
346 	/* Route to xHCI if xHCI enabled */
347 	if (usb_route == ROUTE_TO_XHCI) {
348 		if (is_mem_sr()) {
349 			if (!warm_reset_usb3_ports(xhci_ports))
350 				printk(BIOS_ERR, "USB3 warm reset timed out\n");
351 		}
352 
353 		const uint32_t xhci_port_mask = pci_read_config32(dev, XHCI_USB3PRM) & 0x3f;
354 		pci_update_config32(dev, XHCI_USB3PR, ~XHCI_USB3PR_SSEN, xhci_port_mask);
355 
356 		const uint32_t ehci_port_mask = pci_read_config32(dev, XHCI_USB2PRM) & 0x7fff;
357 		pci_update_config32(dev, XHCI_USB2PR, ~XHCI_USB2PR_HCSEL, ehci_port_mask);
358 	}
359 }
360 
361 /* Do not shift in this macro, as it can cause undefined behaviour for bad port/oc values */
362 #define PORT_TO_OC_SHIFT(port, oc)	((oc) * 8 + (port))
363 
364 /* Avoid shifting into undefined behaviour */
shift_ok(const int shift)365 static inline bool shift_ok(const int shift)
366 {
367 	return shift >= 0 && shift < 32;
368 }
369 
usb_overcurrent_mapping(void)370 static void usb_overcurrent_mapping(void)
371 {
372 	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP);
373 
374 	uint32_t ehci_1_ocmap = 0;
375 	uint32_t ehci_2_ocmap = 0;
376 	uint32_t xhci_1_ocmap = 0;
377 	uint32_t xhci_2_ocmap = 0;
378 
379 	/*
380 	 * EHCI
381 	 */
382 	for (unsigned int idx = 0; idx < physical_port_count(); idx++) {
383 		const struct usb2_port_config *const port = &mainboard_usb2_ports[idx];
384 		printk(BIOS_DEBUG, "USB2 port %u => ", idx);
385 		if (!port->enable) {
386 			printk(BIOS_DEBUG, "disabled\n");
387 			continue;
388 		}
389 		const unsigned short oc_pin = port->oc_pin;
390 		if (oc_pin == USB_OC_PIN_SKIP) {
391 			printk(BIOS_DEBUG, "not mapped to OC pin\n");
392 			continue;
393 		}
394 		/* Ports 0 .. 7 => OC 0 .. 3 */
395 		if (idx < 8 && oc_pin <= 3) {
396 			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin);
397 			if (shift_ok(shift)) {
398 				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin);
399 				ehci_1_ocmap |= 1 << shift;
400 				continue;
401 			}
402 		}
403 		/* Ports 8 .. 13 => OC 4 .. 7 (LPT-H only) */
404 		if (!is_lp && idx >= 8 && oc_pin >= 4) {
405 			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin - 4);
406 			if (shift_ok(shift)) {
407 				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin);
408 				ehci_2_ocmap |= 1 << shift;
409 				continue;
410 			}
411 		}
412 		printk(BIOS_ERR, "Invalid OC pin %u for USB2 port %u\n", oc_pin, idx);
413 	}
414 	printk(BIOS_DEBUG, "\n");
415 	pci_write_config32(PCH_EHCI1_DEV, EHCI_OCMAP, ehci_1_ocmap);
416 	if (!is_lp)
417 		pci_write_config32(PCH_EHCI2_DEV, EHCI_OCMAP, ehci_2_ocmap);
418 
419 	/*
420 	 * xHCI
421 	 */
422 	for (unsigned int idx = 0; idx < ss_port_count(); idx++) {
423 		const struct usb3_port_config *const port = &mainboard_usb3_ports[idx];
424 		printk(BIOS_DEBUG, "USB3 port %u => ", idx);
425 		if (!port->enable) {
426 			printk(BIOS_DEBUG, "disabled\n");
427 			continue;
428 		}
429 		const unsigned short oc_pin = port->oc_pin;
430 		if (oc_pin == USB_OC_PIN_SKIP) {
431 			printk(BIOS_DEBUG, "not mapped to OC pin\n");
432 			continue;
433 		}
434 		/* Ports 0 .. 5 => OC 0 .. 3 */
435 		if (oc_pin <= 3) {
436 			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin);
437 			if (shift_ok(shift)) {
438 				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin);
439 				xhci_1_ocmap |= 1 << shift;
440 				continue;
441 			}
442 		}
443 		/* Ports 0 .. 5 => OC 4 .. 7 (LPT-H only) */
444 		if (!is_lp && oc_pin >= 4) {
445 			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin - 4);
446 			if (shift_ok(shift)) {
447 				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin);
448 				xhci_2_ocmap |= 1 << shift;
449 				continue;
450 			}
451 		}
452 		printk(BIOS_ERR, "Invalid OC pin %u for USB3 port %u\n", oc_pin, idx);
453 	}
454 	printk(BIOS_DEBUG, "\n");
455 	pci_write_config32(PCH_XHCI_DEV, XHCI_U2OCM1, ehci_1_ocmap);
456 	pci_write_config32(PCH_XHCI_DEV, XHCI_U3OCM1, xhci_1_ocmap);
457 	if (!is_lp) {
458 		pci_write_config32(PCH_XHCI_DEV, XHCI_U2OCM2, ehci_2_ocmap);
459 		pci_write_config32(PCH_XHCI_DEV, XHCI_U3OCM2, xhci_2_ocmap);
460 	}
461 }
462 
get_ehci_tune_param_1(const struct usb2_port_config * const port)463 static uint8_t get_ehci_tune_param_1(const struct usb2_port_config *const port)
464 {
465 	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP);
466 
467 	const enum pch_platform_type plat_type = get_pch_platform_type();
468 	const enum usb2_port_location location = port->location;
469 	const uint16_t length = port->length;
470 	if (!is_lp) {
471 		if (plat_type == PCH_TYPE_DESKTOP) {
472 			if (location == USB_PORT_BACK_PANEL)
473 				return 4; /* Back Panel */
474 			else
475 				return 3; /* Front Panel */
476 
477 		} else if (plat_type == PCH_TYPE_MOBILE) {
478 			if (location == USB_PORT_INTERNAL)
479 				return 5; /* Internal Topology */
480 			else if (location == USB_PORT_DOCK)
481 				return 4; /* Dock */
482 			else if (length < 0x70)
483 				return 5; /* Back Panel, less than 7" */
484 			else
485 				return 6; /* Back Panel, 7" or more */
486 		}
487 	} else {
488 		if (location == USB_PORT_BACK_PANEL || location == USB_PORT_MINI_PCIE) {
489 			if (length < 0x70)
490 				return 5; /* Back Panel, less than 7" */
491 			else
492 				return 6; /* Back Panel, 7" or more */
493 		} else if (location == USB_PORT_DOCK) {
494 			return 4; /* Dock */
495 		} else {
496 			return 5; /* Internal Topology */
497 		}
498 	}
499 	printk(BIOS_ERR, "%s: Unhandled case\n", __func__);
500 	return 0;
501 }
502 
get_ehci_tune_param_2(const struct usb2_port_config * const port)503 static uint8_t get_ehci_tune_param_2(const struct usb2_port_config *const port)
504 {
505 	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP);
506 
507 	const enum pch_platform_type plat_type = get_pch_platform_type();
508 	const enum usb2_port_location location = port->location;
509 	const uint16_t length = port->length;
510 	if (!is_lp) {
511 		if (plat_type == PCH_TYPE_DESKTOP) {
512 			if (location == USB_PORT_BACK_PANEL) {
513 				if (length < 0x80)
514 					return 2; /* Back Panel, less than 8" */
515 				else if (length < 0x130)
516 					return 3; /* Back Panel, 8"-13" */
517 				else
518 					return 4; /* Back Panel, 13" or more */
519 			} else {
520 				return 2; /* Front Panel */
521 			}
522 
523 		} else if (plat_type == PCH_TYPE_MOBILE) {
524 			if (location == USB_PORT_INTERNAL) {
525 				return 2; /* Internal Topology */
526 			} else if (location == USB_PORT_DOCK) {
527 				if (length < 0x50)
528 					return 1; /* Dock, less than 5" */
529 				else
530 					return 2; /* Dock, 5" or more */
531 			} else {
532 				if (length < 0x100)
533 					return 2; /* Back Panel, less than 10" */
534 				else
535 					return 3; /* Back Panel, 10" or more */
536 			}
537 		}
538 	} else {
539 		if (location == USB_PORT_BACK_PANEL || location == USB_PORT_MINI_PCIE) {
540 			if (length < 0x100)
541 				return 2; /* Back Panel, less than 10" */
542 			else
543 				return 3; /* Back Panel, 10" or more */
544 		} else if (location == USB_PORT_DOCK) {
545 			if (length < 0x50)
546 				return 1; /* Dock, less than 5" */
547 			else
548 				return 2; /* Dock, 5" or more */
549 		} else {
550 			return 2; /* Internal Topology */
551 		}
552 	}
553 	printk(BIOS_ERR, "%s: Unhandled case\n", __func__);
554 	return 0;
555 }
556 
program_ehci_port_length(void)557 static void program_ehci_port_length(void)
558 {
559 	for (unsigned int port = 0; port < physical_port_count(); port++) {
560 		if (!mainboard_usb2_ports[port].enable)
561 			continue;
562 		const uint32_t addr = 0xe5004000 + (port + 1) * 0x100;
563 		const uint8_t param_1 = get_ehci_tune_param_1(&mainboard_usb2_ports[port]);
564 		const uint8_t param_2 = get_ehci_tune_param_2(&mainboard_usb2_ports[port]);
565 		pch_iobp_update(addr, ~0x7f00, param_2 << 11 | param_1 << 8);
566 	}
567 }
568 
early_usb_init(void)569 void early_usb_init(void)
570 {
571 	/** TODO: Make this configurable? How do the modes affect usbdebug? **/
572 	const enum usb_port_route usb_route = ROUTE_TO_XHCI;
573 	///(pd->boot_mode == 2 && pd->usb_xhci_on_resume) ? ROUTE_TO_XHCI : ROUTE_TO_EHCI;
574 
575 	common_ehci_hcs_init();
576 	xhci_open_memory_space();
577 	common_xhci_hc_init();
578 	perform_xhci_ehci_switching_flow(usb_route);
579 	usb_overcurrent_mapping();
580 	program_ehci_port_length();
581 	/** FIXME: USB per port control is missing, is it needed? **/
582 	xhci_close_memory_space();
583 	/** TODO: Close EHCI memory space? **/
584 }
585