From ee126348726b24fbf6e5435bb2cf15417959a8f7 Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Mon, 5 Feb 2024 18:49:46 -0500 Subject: nb/sandybridge,sb/bd82x6x: Configure USB from southbridge devicetree Transfer all USB responsibilities to southbridge/intel/bd82x6x, using one set of USB port configuration supplied by mainboards in the southbridge section of their devicetree. For MRC raminit, export southbridge_fill_pei_data() as a hook for southbridge code to implement. With new code via this hook, bd82x6x fills pei_data based on this one set of USB port config. For native raminit, early_usb_init() now goes directly to the devicetree and no longer get passed an address to it. TEST=abuild passes for all affected boards. All USB ports still work on asus/p8x7x-series/v/p8z77-m. Change-Id: I38378c7ee0701abc434b030dd97873f2af63e6b0 Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/81881 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/northbridge/intel/sandybridge/pei_data.h | 1 + src/northbridge/intel/sandybridge/raminit_mrc.c | 10 +--- src/northbridge/intel/sandybridge/romstage.c | 2 +- src/southbridge/intel/bd82x6x/early_usb.c | 6 ++- src/southbridge/intel/bd82x6x/early_usb_mrc.c | 62 +++++++++++++++++++++++++ src/southbridge/intel/bd82x6x/pch.h | 2 +- 6 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/northbridge/intel/sandybridge/pei_data.h b/src/northbridge/intel/sandybridge/pei_data.h index 0309cf3b89..db6347c69f 100644 --- a/src/northbridge/intel/sandybridge/pei_data.h +++ b/src/northbridge/intel/sandybridge/pei_data.h @@ -116,4 +116,5 @@ struct pei_data int ddr_refresh_rate_config; } __packed; +void southbridge_fill_pei_data(struct pei_data *pei_data); #endif diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index b9279f3c7c..98b302850c 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -252,11 +252,6 @@ static bool do_pcie_init(void) } } -static void southbridge_fill_pei_data(struct pei_data *pei_data) -{ - /* This will move to southbridge later. */ -} - static void devicetree_fill_pei_data(struct pei_data *pei_data) { const struct northbridge_intel_sandybridge_config *cfg = config_of_soc(); @@ -290,9 +285,6 @@ static void devicetree_fill_pei_data(struct pei_data *pei_data) } } memcpy(pei_data->ts_addresses, cfg->ts_addresses, sizeof(pei_data->ts_addresses)); - - memcpy(pei_data->usb_port_config, cfg->usb_port_config, - sizeof(pei_data->usb_port_config)); } static void spd_fill_pei_data(struct pei_data *pei_data) @@ -374,7 +366,7 @@ void perform_raminit(int s3resume) .nmode = cfg->nmode, .ddr_refresh_rate_config = cfg->ddr_refresh_rate_config, .usb3.mode = cfg->usb3.mode, - .usb3.hs_port_switch_mask = cfg->usb3.hs_port_switch_mask, + /* .usb3.hs_port_switch_mask = native config->xhci_switchable_ports */ .usb3.preboot_support = cfg->usb3.preboot_support, .usb3.xhci_streams = cfg->usb3.xhci_streams, }; diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c index 56dc677d2c..86569c1cb4 100644 --- a/src/northbridge/intel/sandybridge/romstage.c +++ b/src/northbridge/intel/sandybridge/romstage.c @@ -58,7 +58,7 @@ void mainboard_romstage_entry(void) /* When using MRC, USB is initialized by MRC */ if (CONFIG(USE_NATIVE_RAMINIT)) { - early_usb_init(mainboard_usb_ports); + early_usb_init(); } /* Perform some early chipset init needed before RAM initialization can work */ diff --git a/src/southbridge/intel/bd82x6x/early_usb.c b/src/southbridge/intel/bd82x6x/early_usb.c index 6c21cf7fe2..7bca0bbc49 100644 --- a/src/southbridge/intel/bd82x6x/early_usb.c +++ b/src/southbridge/intel/bd82x6x/early_usb.c @@ -8,8 +8,9 @@ #include #include "pch.h" +#include "chip.h" -void early_usb_init(const struct southbridge_usb_port *portmap) +void early_usb_init(void) { u32 reg32; const u32 rcba_dump[8] = { @@ -23,6 +24,9 @@ void early_usb_init(const struct southbridge_usb_port *portmap) USBIR_TXRX_GAIN_DESKTOP6_LOW, USBIR_TXRX_GAIN_DESKTOP6_HIGH, USBIR_TXRX_GAIN_DESKTOP7_LOW, USBIR_TXRX_GAIN_DESKTOP7_MED, 0x20000053, 0x2000055f, 0x20000f5f}; + const struct device *dev = pcidev_on_root(0x1d, 0); + const struct southbridge_intel_bd82x6x_config *config = dev->chip_info; + const struct southbridge_usb_port *portmap = config->usb_port_config; int i; /* Unlock registers. */ diff --git a/src/southbridge/intel/bd82x6x/early_usb_mrc.c b/src/southbridge/intel/bd82x6x/early_usb_mrc.c index f60cc0b706..bf43e263a4 100644 --- a/src/southbridge/intel/bd82x6x/early_usb_mrc.c +++ b/src/southbridge/intel/bd82x6x/early_usb_mrc.c @@ -3,6 +3,8 @@ #include #include #include "pch.h" +#include "chip.h" +#include #define PCH_EHCI1_TEMP_BAR0 0xe8000000 #define PCH_EHCI2_TEMP_BAR0 0xe8000400 @@ -29,3 +31,63 @@ void enable_usb_bar(void) PCH_EHCI2_TEMP_BAR0); pci_or_config16(usb1, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); } + +/* + * Translate coreboot native USB port configuration in devicetree + * into a format reference code expects: + * + * [MRC index] = .native_field // what for + * [0] = .enabled // enable + * [1] = .oc_pin // overcurrent pin + * [2] = .current // length + * + * For .current, use these native values for MRC settings 1-3, corresponding + * to values of 0x40/0x80/0x130, which should produce the correct values + * across all supported PCHs. + * + * PCH type | 1 | 2 | 3 + * ------------+---+---+--- + * Mobile | 0 | 1 | 2 + * Desktop x6x | 6 | 1 | 7 + * Desktop x7x | 8 | 9 | 2 + * + * See also: + * northbridge/intel/sandybridge/pei_data.h + * pch.h + * early_usb.c + */ +void southbridge_fill_pei_data(struct pei_data *pei_data) +{ + const struct device *dev = pcidev_on_root(0x1d, 0); + const struct southbridge_intel_bd82x6x_config *config = dev->chip_info; + /* Native current -> MRC length map to get the same USBIRx register value */ + const uint16_t currents[] = { 0x40, 0x80, 0x130, + 0, 0, 0, /* 3-5 not seen in MRC */ + 0x40, 0x130, 0x40, 0x80}; + for (unsigned int port = 0; port < ARRAY_SIZE(config->usb_port_config); port++) { + uint16_t current = 0; + int ocp = config->usb_port_config[port].oc_pin; + if (ocp == -1) + ocp = (port < 8) ? 0 : 4; + + if (config->usb_port_config[port].current < ARRAY_SIZE(currents)) + current = currents[config->usb_port_config[port].current]; + + /* + * Note for developers: If this message shows, your board uses a + * current setting MRC.bin cannot produce. Choose a value as close + * as possible and test all USB ports, or consider using native raminit. + */ + if (current == 0) { + printk(BIOS_NOTICE, + "%s: USB%02d: %d is an invalid setting for MRC.bin!\n", + __func__, port, config->usb_port_config[port].current); + } + + pei_data->usb_port_config[port][0] = config->usb_port_config[port].enabled; + pei_data->usb_port_config[port][1] = ocp; + pei_data->usb_port_config[port][2] = current; + } + + pei_data->usb3.hs_port_switch_mask = config->xhci_switchable_ports; +} diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h index f2f02b3eab..8924dca54b 100644 --- a/src/southbridge/intel/bd82x6x/pch.h +++ b/src/southbridge/intel/bd82x6x/pch.h @@ -64,7 +64,7 @@ struct southbridge_usb_port void pch_enable(struct device *dev); extern const struct southbridge_usb_port mainboard_usb_ports[14]; -void early_usb_init(const struct southbridge_usb_port *portmap); +void early_usb_init(void); /* PCI Configuration Space (D30:F0): PCI2PCI */ #define PSTS 0x06 -- cgit v1.2.3