vendorcode/amd/opensil/genoa_poc/ramstage.c: Fix log typos
[coreboot2.git] / src / southbridge / intel / bd82x6x / early_usb_mrc.c
blobbf43e263a4848addd5518ab9c8fa57a47949bec8
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/pci_ops.h>
4 #include <device/pci_def.h>
5 #include "pch.h"
6 #include "chip.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,
26 PCH_EHCI1_TEMP_BAR0);
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,
31 PCH_EHCI2_TEMP_BAR0);
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 * ------------+---+---+---
50 * Mobile | 0 | 1 | 2
51 * Desktop x6x | 6 | 1 | 7
52 * Desktop x7x | 8 | 9 | 2
54 * See also:
55 * northbridge/intel/sandybridge/pei_data.h
56 * pch.h
57 * early_usb.c
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++) {
68 uint16_t current = 0;
69 int ocp = config->usb_port_config[port].oc_pin;
70 if (ocp == -1)
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.
81 if (current == 0) {
82 printk(BIOS_NOTICE,
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;