summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/lenovo/x201/romstage.c42
-rw-r--r--src/mainboard/packardbell/ms2290/romstage.c44
-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
5 files changed, 165 insertions, 47 deletions
diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c
index 4f2a3dab31..010ab86887 100644
--- a/src/mainboard/lenovo/x201/romstage.c
+++ b/src/mainboard/lenovo/x201/romstage.c
@@ -61,6 +61,24 @@ static void pch_enable_lpc(void)
pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR);
}
+const struct southbridge_usb_port mainboard_usb_ports[] = {
+ /* Enabled, Current table lookup index, OC map */
+ { 1, IF1_557, 0 },
+ { 1, IF1_55F, 1 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_557, 3 },
+ { 1, IF1_14B, 3 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_74B, 4 },
+ { 1, IF1_74B, 5 },
+ { 1, IF1_55F, 7 },
+ { 1, IF1_55F, 7 },
+ { 1, IF1_557, 7 },
+ { 1, IF1_55F, 7 },
+};
+
static void rcba_config(void)
{
southbridge_configure_default_intmap();
@@ -73,29 +91,7 @@ static void rcba_config(void)
/* Set reserved bit to 1 */
RCBA32(FD2) = 1;
- static const u32 rcba_dump3[] = {
- /* 3500 */ 0x20000557, 0x2000055f, 0x2000074b, 0x2000074b,
- /* 3510 */ 0x20000557, 0x2000014b, 0x2000074b, 0x2000074b,
- /* 3520 */ 0x2000074b, 0x2000074b, 0x2000055f, 0x2000055f,
- /* 3530 */ 0x20000557, 0x2000055f, 0x00000000, 0x00000000,
- /* 3540 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 3550 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 3560 */ 0x00000001, 0x000026a3, 0x00040002, 0x01000052,
- /* 3570 */ 0x02000772, 0x16000f8f, 0x1800ff4f, 0x0001d630,
- /* 3580 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 3590 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35a0 */ 0xfc000201, 0x3c000201, 0x00000000, 0x00000000,
- /* 35b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- };
- unsigned i;
- for (i = 0; i < sizeof(rcba_dump3) / 4; i++) {
- RCBA32(4 * i + 0x3500) = rcba_dump3[i];
- (void)RCBA32(4 * i + 0x3500);
- }
+ early_usb_init(mainboard_usb_ports);
}
static inline void write_acpi32(u32 addr, u32 val)
diff --git a/src/mainboard/packardbell/ms2290/romstage.c b/src/mainboard/packardbell/ms2290/romstage.c
index a292f7ba77..2aeee1ec3a 100644
--- a/src/mainboard/packardbell/ms2290/romstage.c
+++ b/src/mainboard/packardbell/ms2290/romstage.c
@@ -56,6 +56,25 @@ static void pch_enable_lpc(void)
pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR);
}
+/* Seems copied from Lenovo Thinkpad x201, might be wrong */
+const struct southbridge_usb_port mainboard_usb_ports[] = {
+ /* Enabled, Current table lookup index, OC map */
+ { 1, IF1_557, 0 },
+ { 1, IF1_55F, 1 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_557, 3 },
+ { 1, IF1_14B, 3 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_74B, 3 },
+ { 1, IF1_74B, 4 },
+ { 1, IF1_74B, 5 },
+ { 1, IF1_55F, 7 },
+ { 1, IF1_55F, 7 },
+ { 1, IF1_557, 7 },
+ { 1, IF1_55F, 7 },
+};
+
static void rcba_config(void)
{
southbridge_configure_default_intmap();
@@ -68,30 +87,7 @@ static void rcba_config(void)
/* Set reserved bit to 1 */
RCBA32(FD2) = 1;
- static const u32 rcba_dump3[] = {
- /* 3500 */ 0x20000557, 0x2000055f, 0x2000074b, 0x2000074b,
- /* 3510 */ 0x20000557, 0x2000014b, 0x2000074b, 0x2000074b,
- /* 3520 */ 0x2000074b, 0x2000074b, 0x2000055f, 0x2000055f,
- /* 3530 */ 0x20000557, 0x2000055f, 0x00000000, 0x00000000,
- /* 3540 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 3550 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 3560 */ 0x00000001, 0x000026a3, 0x00040002, 0x01000052,
- /* 3570 */ 0x02000772, 0x16000f8f, 0x1800ff4f, 0x0001d630,
- /* 3580 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 3590 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35a0 */ 0xfc000201, 0x3c000201, 0x00000000, 0x00000000,
- /* 35b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- /* 35f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- };
- unsigned i;
-
- for (i = 0; i < sizeof(rcba_dump3) / 4; i++) {
- RCBA32(4 * i + 0x3500) = rcba_dump3[i];
- (void)RCBA32(4 * i + 0x3500);
- }
+ early_usb_init(mainboard_usb_ports);
}
static inline void write_acpi32(u32 addr, u32 val)
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)