aboutsummaryrefslogtreecommitdiff
path: root/src/southbridge/intel/i82801ix/dmi_setup.c
diff options
context:
space:
mode:
authorPatrick Georgi <patrick.georgi@secunet.com>2012-11-06 11:05:09 +0100
committerPatrick Georgi <patrick@georgi-clan.de>2012-11-27 09:16:58 +0100
commite72a8a3047c535bda03aecce2eca134608d1a93c (patch)
tree24d0980742dfa5aba5c286c6d2236cfed0ff92f6 /src/southbridge/intel/i82801ix/dmi_setup.c
parent2efc8808b8bfaee0a0e8f3ee387ecd9a3f049705 (diff)
intel/i82801ix: new southbridge, ICH9
Add support for ICH9 southbridge Change-Id: I70612431101bf48d9dcc96ee1b37d257c9ad2ee2 Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com> Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: http://review.coreboot.org/1690 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/southbridge/intel/i82801ix/dmi_setup.c')
-rw-r--r--src/southbridge/intel/i82801ix/dmi_setup.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/southbridge/intel/i82801ix/dmi_setup.c b/src/southbridge/intel/i82801ix/dmi_setup.c
new file mode 100644
index 0000000000..73703b4f83
--- /dev/null
+++ b/src/southbridge/intel/i82801ix/dmi_setup.c
@@ -0,0 +1,147 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_def.h>
+#include <console/console.h>
+#include <northbridge/intel/gm45/gm45.h>
+#include "i82801ix.h"
+
+/* VC1 Port Arbitration Table */
+static const u8 vc1_pat[] = {
+ 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0f, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0f, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+void i82801ix_dmi_setup(void)
+{
+ int i;
+ u32 reg32;
+
+ RCBA32(RCBA_V1CAP) = (RCBA32(RCBA_V1CAP) & ~(0x7f<<16)) | (0x12<<16);
+
+ RCBA32(0x0088) = 0x00109000;
+ RCBA16(0x01fc) = 0x060b;
+ RCBA32(0x01f4) = 0x86000040;
+ RCBA8 (0x0220) = 0x45;
+ RCBA32(0x2024) &= ~(1 << 7);
+
+
+ /* VC1 setup for isochronous transfers: */
+
+ /* Set VC1 virtual channel id to 1. */
+ RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7 << 24)) | (0x1 << 24);
+ /* Enable TC7 traffic on VC1. */
+ RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7f << 1)) | (1 << 7);
+ /* Disable TC7-TC1 traffic on VC0. */
+ RCBA32(RCBA_V0CTL) &= ~(0x7f << 1);
+ /* TC7-TC1 traffic on PCIe root ports will be disabled in pci driver. */
+
+ /* Set table type to time-based WRR. */
+ RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7 << 17)) | (0x4 << 17);
+ /* Program port arbitration table. */
+ for (i = 0; i < sizeof(vc1_pat); ++i)
+ RCBA8(RCBA_PAT + i) = vc1_pat[i];
+ /* Load port arbitration table. */
+ RCBA32(RCBA_V1CTL) |= (1 << 16);
+
+ /* Enable VC1. */
+ RCBA32(RCBA_V1CTL) |= (1 << 31);
+
+
+ /* Setup RCRB: */
+
+ /* Set component id to 2 for southbridge, northbridge has id 1. */
+ RCBA8(RCBA_ESD + 2) = 2;
+ /* Set target port number and target component id of the northbridge. */
+ RCBA8(RCBA_ULD + 3) = 1;
+ RCBA8(RCBA_ULD + 2) = 1;
+ /* Set target rcrb base address, i.e. DMIBAR. */
+ RCBA32(RCBA_ULBA) = DEFAULT_DMIBAR;
+
+ /* Enable ASPM. */
+ if (LPC_IS_MOBILE(PCI_DEV(0, 0x1f, 0))) {
+ reg32 = RCBA32(RCBA_DMC);
+ /* Enable mobile specific power saving (set this first). */
+ reg32 = (reg32 & ~(3 << 10)) | (1 << 10);
+ RCBA32(RCBA_DMC) = reg32;
+ /* Enable DMI power savings. */
+ reg32 |= (1 << 19);
+ RCBA32(RCBA_DMC) = reg32;
+ /* Advertise L0s and L1. */
+ RCBA32(RCBA_LCAP) |= (3 << 10);
+ /* Enable L0s and L1. */
+ RCBA32(RCBA_LCTL) |= (3 << 0);
+ } else {
+ /* Enable DMI power savings. */
+ RCBA32(RCBA_DMC) |= (1 << 19);
+ /* Advertise L0s only. */
+ RCBA32(RCBA_LCAP) = (RCBA32(RCBA_LCAP) & ~(3<<10)) | (1<<10);
+ /* Enable L0s only. */
+ RCBA32(RCBA_LCTL) = (RCBA32(RCBA_LCTL) & ~(3<< 0)) | (1<< 0);
+ }
+}
+
+/* Should be called after VC1 has been enabled on both sides. */
+void i82801ix_dmi_poll_vc1(void)
+{
+ int timeout;
+
+ timeout = 0x7ffff;
+ printk(BIOS_DEBUG, "ICH9 waits for VC1 negotiation... ");
+ while ((RCBA32(RCBA_V1STS) & (1 << 1)) && --timeout) {}
+ if (!timeout)
+ printk(BIOS_DEBUG, "timeout!\n");
+ else
+ printk(BIOS_DEBUG, "done.\n");
+
+ /* Check for x2 DMI link. */
+ if (((RCBA16(RCBA_LSTS) >> 4) & 0x3f) == 2) {
+ printk(BIOS_DEBUG, "x2 DMI link detected.\n");
+ RCBA32(0x2024) = (RCBA32(0x2024) & ~(7 << 21)) | (3 << 21);
+ RCBA16(0x20c4) |= (1 << 15);
+ RCBA16(0x20e4) |= (1 << 15);
+ /* TODO: Maybe we have to save and
+ restore these settings across S3. */
+ }
+
+ timeout = 0x7ffff;
+ printk(BIOS_DEBUG, "ICH9 waits for port arbitration table update... ");
+ while ((RCBA32(RCBA_V1STS) & (1 << 0)) && --timeout) {}
+ if (!timeout)
+ printk(BIOS_DEBUG, "timeout!\n");
+ else
+ printk(BIOS_DEBUG, "done.\n");
+}
+