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 <buurin@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81881 Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
@ -116,4 +116,5 @@ struct pei_data
|
|||||||
int ddr_refresh_rate_config;
|
int ddr_refresh_rate_config;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
void southbridge_fill_pei_data(struct pei_data *pei_data);
|
||||||
#endif
|
#endif
|
||||||
|
@ -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)
|
static void devicetree_fill_pei_data(struct pei_data *pei_data)
|
||||||
{
|
{
|
||||||
const struct northbridge_intel_sandybridge_config *cfg = config_of_soc();
|
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->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)
|
static void spd_fill_pei_data(struct pei_data *pei_data)
|
||||||
@ -374,7 +366,7 @@ void perform_raminit(int s3resume)
|
|||||||
.nmode = cfg->nmode,
|
.nmode = cfg->nmode,
|
||||||
.ddr_refresh_rate_config = cfg->ddr_refresh_rate_config,
|
.ddr_refresh_rate_config = cfg->ddr_refresh_rate_config,
|
||||||
.usb3.mode = cfg->usb3.mode,
|
.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.preboot_support = cfg->usb3.preboot_support,
|
||||||
.usb3.xhci_streams = cfg->usb3.xhci_streams,
|
.usb3.xhci_streams = cfg->usb3.xhci_streams,
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ void mainboard_romstage_entry(void)
|
|||||||
|
|
||||||
/* When using MRC, USB is initialized by MRC */
|
/* When using MRC, USB is initialized by MRC */
|
||||||
if (CONFIG(USE_NATIVE_RAMINIT)) {
|
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 */
|
/* Perform some early chipset init needed before RAM initialization can work */
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
#include <southbridge/intel/common/pmbase.h>
|
#include <southbridge/intel/common/pmbase.h>
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
void early_usb_init(const struct southbridge_usb_port *portmap)
|
void early_usb_init(void)
|
||||||
{
|
{
|
||||||
u32 reg32;
|
u32 reg32;
|
||||||
const u32 rcba_dump[8] = {
|
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_DESKTOP6_LOW, USBIR_TXRX_GAIN_DESKTOP6_HIGH,
|
||||||
USBIR_TXRX_GAIN_DESKTOP7_LOW, USBIR_TXRX_GAIN_DESKTOP7_MED,
|
USBIR_TXRX_GAIN_DESKTOP7_LOW, USBIR_TXRX_GAIN_DESKTOP7_MED,
|
||||||
0x20000053, 0x2000055f, 0x20000f5f};
|
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;
|
int i;
|
||||||
|
|
||||||
/* Unlock registers. */
|
/* Unlock registers. */
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <device/pci_ops.h>
|
#include <device/pci_ops.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "chip.h"
|
||||||
|
#include <northbridge/intel/sandybridge/pei_data.h>
|
||||||
|
|
||||||
#define PCH_EHCI1_TEMP_BAR0 0xe8000000
|
#define PCH_EHCI1_TEMP_BAR0 0xe8000000
|
||||||
#define PCH_EHCI2_TEMP_BAR0 0xe8000400
|
#define PCH_EHCI2_TEMP_BAR0 0xe8000400
|
||||||
@ -29,3 +31,63 @@ void enable_usb_bar(void)
|
|||||||
PCH_EHCI2_TEMP_BAR0);
|
PCH_EHCI2_TEMP_BAR0);
|
||||||
pci_or_config16(usb1, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
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;
|
||||||
|
}
|
||||||
|
@ -64,7 +64,7 @@ struct southbridge_usb_port
|
|||||||
void pch_enable(struct device *dev);
|
void pch_enable(struct device *dev);
|
||||||
extern const struct southbridge_usb_port mainboard_usb_ports[14];
|
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 */
|
/* PCI Configuration Space (D30:F0): PCI2PCI */
|
||||||
#define PSTS 0x06
|
#define PSTS 0x06
|
||||||
|
Reference in New Issue
Block a user