summaryrefslogtreecommitdiff
path: root/src/southbridge/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/intel')
-rw-r--r--src/southbridge/intel/ibexpeak/Makefile.inc1
-rw-r--r--src/southbridge/intel/ibexpeak/early_usb.c71
-rw-r--r--src/southbridge/intel/ibexpeak/pch.h54
3 files changed, 126 insertions, 0 deletions
diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc
index 9caf29fd87..f22be2453b 100644
--- a/src/southbridge/intel/ibexpeak/Makefile.inc
+++ b/src/southbridge/intel/ibexpeak/Makefile.inc
@@ -43,5 +43,6 @@ romstage-y +=../bd82x6x/me_status.c
romstage-y += early_thermal.c
romstage-y += ../bd82x6x/early_rcba.c
romstage-y += early_cir.c
+romstage-y += early_usb.c
endif
diff --git a/src/southbridge/intel/ibexpeak/early_usb.c b/src/southbridge/intel/ibexpeak/early_usb.c
new file mode 100644
index 0000000000..53c4ae7a95
--- /dev/null
+++ b/src/southbridge/intel/ibexpeak/early_usb.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Vladimir Serbinenko
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/mmio.h>
+#include <device/pci_ops.h>
+#include <device/pci_def.h>
+#include <northbridge/intel/sandybridge/sandybridge.h>
+#include <southbridge/intel/common/rcba.h>
+#include <southbridge/intel/common/pmbase.h>
+
+#include "pch.h"
+
+#define TOTAL_USB_PORTS 14
+
+void early_usb_init(const struct southbridge_usb_port *portmap)
+{
+ u32 reg32;
+ const u16 currents[] = { 0xf57, 0xf5f, 0x753, 0x75f, 0x14b, 0x74b,
+ 0x557, 0x757, 0x55f, 0x54b
+ };
+ int i;
+
+ /* Unlock registers. */
+ write_pmbase16(UPRWC, read_pmbase16(UPRWC) | UPRWC_WR_EN);
+
+ for (i = 0; i < TOTAL_USB_PORTS; i++)
+ RCBA32_AND_OR(USBIR0 + 4 * i, ~0xfff, currents[portmap[i].current]);
+
+ /* USB Initialization Registers. We follow what EDS recommends here.
+ TODO maybe vendor firmware values are better? */
+ RCBA32(USBIRC) &= ~(1 << 8);
+ RCBA32_OR(USBIRA, (7 << 12) | (7 << 8) | (7 << 4) | (2 << 0));
+ RCBA32_AND_OR(USBIRB, ~0x617f0, (3 << 17) | (1 << 12) | (1 << 10)
+ | (1 << 8) | (4 << 4));
+ /* Set to Rate Matching Hub Mode to make PCI devices appear. */
+ RCBA32(0x3598) = 0;
+
+ reg32 = 0;
+ for (i = 0; i < TOTAL_USB_PORTS; i++)
+ if (!portmap[i].enabled)
+ reg32 |= (1 << i);
+ RCBA32(USBPDO) = reg32;
+ reg32 = 0;
+ /* The OC pins of the first 8 USB ports are mapped in USBOCM1 */
+ for (i = 0; i < 8; i++)
+ if (portmap[i].enabled && portmap[i].oc_pin >= 0)
+ reg32 |= (1 << (i + 8 * portmap[i].oc_pin));
+ RCBA32(USBOCM1) = reg32;
+ reg32 = 0;
+ /* The OC pins of the remainder 6 USB ports are mapped in USBOCM2 */
+ for (i = 8; i < TOTAL_USB_PORTS; i++)
+ if (portmap[i].enabled && portmap[i].oc_pin >= 4)
+ reg32 |= (1 << (i - 8 + 8 * (portmap[i].oc_pin - 4)));
+ RCBA32(USBOCM2) = reg32;
+
+ /* Relock registers. */
+ write_pmbase16(UPRWC, 0);
+}
diff --git a/src/southbridge/intel/ibexpeak/pch.h b/src/southbridge/intel/ibexpeak/pch.h
index 34f80330bc..556b9e0a0b 100644
--- a/src/southbridge/intel/ibexpeak/pch.h
+++ b/src/southbridge/intel/ibexpeak/pch.h
@@ -66,6 +66,26 @@ void early_thermal_init(void);
void southbridge_configure_default_intmap(void);
void pch_setup_cir(int chipset_type);
+enum current_lookup_idx {
+ IF1_F57 = 0,
+ IF1_F5F,
+ IF1_753,
+ IF1_75F,
+ IF1_14B,
+ IF1_74B,
+ IF1_557,
+ IF1_757,
+ IF1_55F,
+ IF1_54B,
+};
+
+struct southbridge_usb_port {
+ int enabled;
+ enum current_lookup_idx current;
+ int oc_pin;
+};
+void early_usb_init(const struct southbridge_usb_port *portmap);
+
#ifndef __ROMCC__
#include <device/device.h>
void pch_enable(struct device *dev);
@@ -75,6 +95,10 @@ void pch_enable(struct device *dev);
#define MAINBOARD_POWER_ON 1
#define MAINBOARD_POWER_KEEP 2
+/* PM I/O Space */
+#define UPRWC 0x3c
+#define UPRWC_WR_EN (1 << 1) /* USB Per-Port Registers Write Enable */
+
/* PCI Configuration Space (D30:F0): PCI2PCI */
#define PSTS 0x06
#define SMLT 0x1b
@@ -401,6 +425,36 @@ void pch_enable(struct device *dev);
#define PCH_DISABLE_MEI1 (1 << 1)
#define PCH_ENABLE_DBDF (1 << 0)
+/* USB Initialization Registers[13:0] */
+#define USBIR0 0x3500 /* 32bit */
+#define USBIR1 0x3504 /* 32bit */
+#define USBIR2 0x3508 /* 32bit */
+#define USBIR3 0x350c /* 32bit */
+#define USBIR4 0x3510 /* 32bit */
+#define USBIR5 0x3514 /* 32bit */
+#define USBIR6 0x3518 /* 32bit */
+#define USBIR7 0x351c /* 32bit */
+#define USBIR8 0x3520 /* 32bit */
+#define USBIR9 0x3524 /* 32bit */
+#define USBIR10 0x3528 /* 32bit */
+#define USBIR11 0x352c /* 32bit */
+#define USBIR12 0x3530 /* 32bit */
+#define USBIR13 0x3534 /* 32bit */
+
+#define USBIRC 0x3564 /* 32bit */
+#define USBIRA 0x3570 /* 32bit */
+#define USBIRB 0x357c /* 32bit */
+
+/* Miscellaneous Control Register */
+#define MISCCTL 0x3590 /* 32bit */
+/* USB Port Disable Override */
+#define USBPDO 0x359c /* 32bit */
+/* USB Overcurrent MAP Register */
+#define USBOCM1 0x35a0 /* 32bit */
+#define USBOCM2 0x35a4 /* 32bit */
+/* Rate Matching Hub Wake Control Register */
+#define RMHWKCTL 0x35b0 /* 32bit */
+
/* ICH7 PMBASE */
#define PM1_STS 0x00
#define WAK_STS (1 << 15)