1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/pci_ops.h>
4 #include <device/pci_def.h>
7 #include <northbridge/intel/sandybridge/pei_data.h>
9 #define PCH_EHCI1_TEMP_BAR0 0xe8000000
10 #define PCH_EHCI2_TEMP_BAR0 0xe8000400
13 * Setup USB controller MMIO BAR to prevent the
14 * reference code from resetting the controller.
16 * The BAR will be re-assigned during device
17 * enumeration so these are only temporary.
19 void enable_usb_bar(void)
21 pci_devfn_t usb0
= PCH_EHCI1_DEV
;
22 pci_devfn_t usb1
= PCH_EHCI2_DEV
;
24 /* USB Controller 1 */
25 pci_write_config32(usb0
, PCI_BASE_ADDRESS_0
,
27 pci_or_config16(usb0
, PCI_COMMAND
, PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
29 /* USB Controller 2 */
30 pci_write_config32(usb1
, PCI_BASE_ADDRESS_0
,
32 pci_or_config16(usb1
, PCI_COMMAND
, PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
36 * Translate coreboot native USB port configuration in devicetree
37 * into a format reference code expects:
39 * [MRC index] = .native_field // what for
40 * [0] = .enabled // enable
41 * [1] = .oc_pin // overcurrent pin
42 * [2] = .current // length
44 * For .current, use these native values for MRC settings 1-3, corresponding
45 * to values of 0x40/0x80/0x130, which should produce the correct values
46 * across all supported PCHs.
48 * PCH type | 1 | 2 | 3
49 * ------------+---+---+---
51 * Desktop x6x | 6 | 1 | 7
52 * Desktop x7x | 8 | 9 | 2
55 * northbridge/intel/sandybridge/pei_data.h
59 void southbridge_fill_pei_data(struct pei_data
*pei_data
)
61 const struct device
*dev
= pcidev_on_root(0x1d, 0);
62 const struct southbridge_intel_bd82x6x_config
*config
= dev
->chip_info
;
63 /* Native current -> MRC length map to get the same USBIRx register value */
64 const uint16_t currents
[] = { 0x40, 0x80, 0x130,
65 0, 0, 0, /* 3-5 not seen in MRC */
66 0x40, 0x130, 0x40, 0x80};
67 for (unsigned int port
= 0; port
< ARRAY_SIZE(config
->usb_port_config
); port
++) {
69 int ocp
= config
->usb_port_config
[port
].oc_pin
;
71 ocp
= (port
< 8) ? 0 : 4;
73 if (config
->usb_port_config
[port
].current
< ARRAY_SIZE(currents
))
74 current
= currents
[config
->usb_port_config
[port
].current
];
77 * Note for developers: If this message shows, your board uses a
78 * current setting MRC.bin cannot produce. Choose a value as close
79 * as possible and test all USB ports, or consider using native raminit.
83 "%s: USB%02d: %d is an invalid setting for MRC.bin!\n",
84 __func__
, port
, config
->usb_port_config
[port
].current
);
87 pei_data
->usb_port_config
[port
][0] = config
->usb_port_config
[port
].enabled
;
88 pei_data
->usb_port_config
[port
][1] = ocp
;
89 pei_data
->usb_port_config
[port
][2] = current
;
92 pei_data
->usb3
.hs_port_switch_mask
= config
->xhci_switchable_ports
;