summaryrefslogtreecommitdiff
path: root/src/northbridge/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/intel')
-rw-r--r--src/northbridge/intel/haswell/pei_data.h26
-rw-r--r--src/northbridge/intel/haswell/raminit.c41
-rw-r--r--src/northbridge/intel/haswell/raminit.h37
3 files changed, 85 insertions, 19 deletions
diff --git a/src/northbridge/intel/haswell/pei_data.h b/src/northbridge/intel/haswell/pei_data.h
index 14d8b719a9..c455e17d45 100644
--- a/src/northbridge/intel/haswell/pei_data.h
+++ b/src/northbridge/intel/haswell/pei_data.h
@@ -10,30 +10,30 @@ typedef void (*tx_byte_func)(unsigned char byte);
#define SPD_LEN 256
-#define USB_OC_PIN_SKIP 8
+#define PEI_USB_OC_PIN_SKIP 8
-enum usb2_port_location {
- USB_PORT_BACK_PANEL = 0,
- USB_PORT_FRONT_PANEL,
- USB_PORT_DOCK,
- USB_PORT_MINI_PCIE,
- USB_PORT_FLEX,
- USB_PORT_INTERNAL,
- USB_PORT_SKIP
+enum pei_usb2_port_location {
+ PEI_USB_PORT_BACK_PANEL = 0,
+ PEI_USB_PORT_FRONT_PANEL,
+ PEI_USB_PORT_DOCK,
+ PEI_USB_PORT_MINI_PCIE,
+ PEI_USB_PORT_FLEX,
+ PEI_USB_PORT_INTERNAL,
+ PEI_USB_PORT_SKIP
};
/* Usb Port Length:
* [16:4] = length in inches in octal format
* [3:0] = decimal point
*/
-struct usb2_port_setting {
+struct pei_usb2_port_setting {
uint16_t length;
uint8_t enable;
uint8_t over_current_pin;
uint8_t location;
} __packed;
-struct usb3_port_setting {
+struct pei_usb3_port_setting {
uint8_t enable;
uint8_t over_current_pin;
} __packed;
@@ -80,8 +80,8 @@ struct pei_data
uint32_t max_ddr3_freq;
/* Route all USB ports to XHCI controller in resume path */
int usb_xhci_on_resume;
- struct usb2_port_setting usb2_ports[16];
- struct usb3_port_setting usb3_ports[16];
+ struct pei_usb2_port_setting usb2_ports[16];
+ struct pei_usb3_port_setting usb3_ports[16];
uint8_t spd_data[4][SPD_LEN];
tx_byte_func tx_byte;
} __packed;
diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c
index 1f84ffa5cb..5da11299ba 100644
--- a/src/northbridge/intel/haswell/raminit.c
+++ b/src/northbridge/intel/haswell/raminit.c
@@ -309,6 +309,25 @@ static int make_channel_disabled_mask(const struct pei_data *pd, int ch)
return (!pd->spd_addresses[ch + ch] << 0) | (!pd->spd_addresses[ch + ch + 1] << 1);
}
+static enum pei_usb2_port_location map_to_pei_usb2_location(const enum usb2_port_location loc)
+{
+ static const enum pei_usb2_port_location map[] = {
+ [USB_PORT_SKIP] = PEI_USB_PORT_SKIP,
+ [USB_PORT_BACK_PANEL] = PEI_USB_PORT_BACK_PANEL,
+ [USB_PORT_FRONT_PANEL] = PEI_USB_PORT_FRONT_PANEL,
+ [USB_PORT_DOCK] = PEI_USB_PORT_DOCK,
+ [USB_PORT_MINI_PCIE] = PEI_USB_PORT_MINI_PCIE,
+ [USB_PORT_FLEX] = PEI_USB_PORT_FLEX,
+ [USB_PORT_INTERNAL] = PEI_USB_PORT_INTERNAL,
+ };
+ return loc >= ARRAY_SIZE(map) ? PEI_USB_PORT_SKIP : map[loc];
+}
+
+static uint8_t map_to_pei_oc_pin(const uint8_t oc_pin)
+{
+ return oc_pin >= USB_OC_PIN_SKIP ? PEI_USB_OC_PIN_SKIP : oc_pin;
+}
+
void perform_raminit(const int s3resume)
{
const struct device *gbe = pcidev_on_root(0x19, 0);
@@ -337,8 +356,26 @@ void perform_raminit(const int s3resume)
.usb_xhci_on_resume = cfg->usb_xhci_on_resume,
};
- memcpy(pei_data.usb2_ports, mainboard_usb2_ports, sizeof(mainboard_usb2_ports));
- memcpy(pei_data.usb3_ports, mainboard_usb3_ports, sizeof(mainboard_usb3_ports));
+ for (size_t i = 0; i < ARRAY_SIZE(mainboard_usb2_ports); i++) {
+ /* If a port is not enabled, skip it */
+ if (!mainboard_usb2_ports[i].enable) {
+ pei_data.usb2_ports[i].over_current_pin = PEI_USB_OC_PIN_SKIP;
+ pei_data.usb2_ports[i].location = PEI_USB_PORT_SKIP;
+ continue;
+ }
+ const enum usb2_port_location loc = mainboard_usb2_ports[i].location;
+ const uint8_t oc_pin = mainboard_usb2_ports[i].oc_pin;
+ pei_data.usb2_ports[i].length = mainboard_usb2_ports[i].length;
+ pei_data.usb2_ports[i].enable = mainboard_usb2_ports[i].enable;
+ pei_data.usb2_ports[i].over_current_pin = map_to_pei_oc_pin(oc_pin);
+ pei_data.usb2_ports[i].location = map_to_pei_usb2_location(loc);
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(mainboard_usb3_ports); i++) {
+ const uint8_t oc_pin = mainboard_usb3_ports[i].oc_pin;
+ pei_data.usb3_ports[i].enable = mainboard_usb3_ports[i].enable;
+ pei_data.usb3_ports[i].over_current_pin = map_to_pei_oc_pin(oc_pin);
+ }
/* MRC has hardcoded assumptions of 2 meaning S3 wake. Normalize it here. */
pei_data.boot_mode = s3resume ? 2 : 0;
diff --git a/src/northbridge/intel/haswell/raminit.h b/src/northbridge/intel/haswell/raminit.h
index 400ac2d4ce..c0f6c639d3 100644
--- a/src/northbridge/intel/haswell/raminit.h
+++ b/src/northbridge/intel/haswell/raminit.h
@@ -3,8 +3,7 @@
#ifndef RAMINIT_H
#define RAMINIT_H
-#include <stdint.h>
-#include "pei_data.h"
+#include <types.h>
#define SPD_MEMORY_DOWN 0xff
@@ -21,9 +20,39 @@ struct spd_info {
#define MAX_USB3_PORTS 6
#endif
+/* There are 8 OC pins */
+#define USB_OC_PIN_SKIP 8
+
+enum usb2_port_location {
+ USB_PORT_SKIP = 0,
+ USB_PORT_BACK_PANEL,
+ USB_PORT_FRONT_PANEL,
+ USB_PORT_DOCK,
+ USB_PORT_MINI_PCIE,
+ USB_PORT_FLEX,
+ USB_PORT_INTERNAL,
+};
+
+/*
+ * USB port length is in MRC format: binary-coded decimal length in tenths of an inch.
+ * 4.2 inches -> 0x0042
+ * 12.7 inches -> 0x0127
+ */
+struct usb2_port_config {
+ uint16_t length;
+ bool enable;
+ unsigned short oc_pin;
+ enum usb2_port_location location;
+};
+
+struct usb3_port_config {
+ bool enable;
+ unsigned int oc_pin;
+};
+
/* Mainboard-specific USB configuration */
-extern const struct usb2_port_setting mainboard_usb2_ports[MAX_USB2_PORTS];
-extern const struct usb3_port_setting mainboard_usb3_ports[MAX_USB3_PORTS];
+extern const struct usb2_port_config mainboard_usb2_ports[MAX_USB2_PORTS];
+extern const struct usb3_port_config mainboard_usb3_ports[MAX_USB3_PORTS];
/* Mainboard callback to fill in the SPD addresses */
void mb_get_spd_map(struct spd_info *spdi);