blob: e47586b1ed1d3cb24fc3fd7a97c2154ea6254556 [file] [log] [blame]
Patrick Georgie72a8a32012-11-06 11:05:09 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Patrick Georgie72a8a32012-11-06 11:05:09 +010015 */
16
17#include <arch/io.h>
Patrick Georgie72a8a32012-11-06 11:05:09 +010018#include <device/pci_def.h>
19#include <console/console.h>
20#include <northbridge/intel/gm45/gm45.h>
21#include "i82801ix.h"
22
23/* VC1 Port Arbitration Table */
24static const u8 vc1_pat[] = {
25 0x0f, 0x00, 0x00, 0x00,
26 0x00, 0x00, 0x0f, 0x00,
27 0x00, 0x00, 0x00, 0x00,
28 0xf0, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x0f,
30 0x00, 0x00, 0x00, 0x00,
31 0x00, 0xf0, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00,
33 0x0f, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x0f, 0x00,
35 0x00, 0x00, 0x00, 0x00,
36 0xf0, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x0f,
38 0x00, 0x00, 0x00, 0x00,
39 0x00, 0xf0, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00,
41};
42void i82801ix_dmi_setup(void)
43{
44 int i;
45 u32 reg32;
46
47 RCBA32(RCBA_V1CAP) = (RCBA32(RCBA_V1CAP) & ~(0x7f<<16)) | (0x12<<16);
48
49 RCBA32(0x0088) = 0x00109000;
50 RCBA16(0x01fc) = 0x060b;
51 RCBA32(0x01f4) = 0x86000040;
52 RCBA8 (0x0220) = 0x45;
53 RCBA32(0x2024) &= ~(1 << 7);
54
55
56 /* VC1 setup for isochronous transfers: */
57
58 /* Set VC1 virtual channel id to 1. */
59 RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7 << 24)) | (0x1 << 24);
60 /* Enable TC7 traffic on VC1. */
61 RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7f << 1)) | (1 << 7);
62 /* Disable TC7-TC1 traffic on VC0. */
63 RCBA32(RCBA_V0CTL) &= ~(0x7f << 1);
64 /* TC7-TC1 traffic on PCIe root ports will be disabled in pci driver. */
65
66 /* Set table type to time-based WRR. */
67 RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7 << 17)) | (0x4 << 17);
68 /* Program port arbitration table. */
69 for (i = 0; i < sizeof(vc1_pat); ++i)
70 RCBA8(RCBA_PAT + i) = vc1_pat[i];
71 /* Load port arbitration table. */
72 RCBA32(RCBA_V1CTL) |= (1 << 16);
73
74 /* Enable VC1. */
75 RCBA32(RCBA_V1CTL) |= (1 << 31);
76
77
78 /* Setup RCRB: */
79
80 /* Set component id to 2 for southbridge, northbridge has id 1. */
81 RCBA8(RCBA_ESD + 2) = 2;
82 /* Set target port number and target component id of the northbridge. */
83 RCBA8(RCBA_ULD + 3) = 1;
84 RCBA8(RCBA_ULD + 2) = 1;
85 /* Set target rcrb base address, i.e. DMIBAR. */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080086 RCBA32(RCBA_ULBA) = (uintptr_t)DEFAULT_DMIBAR;
Patrick Georgie72a8a32012-11-06 11:05:09 +010087
88 /* Enable ASPM. */
89 if (LPC_IS_MOBILE(PCI_DEV(0, 0x1f, 0))) {
90 reg32 = RCBA32(RCBA_DMC);
91 /* Enable mobile specific power saving (set this first). */
92 reg32 = (reg32 & ~(3 << 10)) | (1 << 10);
93 RCBA32(RCBA_DMC) = reg32;
94 /* Enable DMI power savings. */
95 reg32 |= (1 << 19);
96 RCBA32(RCBA_DMC) = reg32;
97 /* Advertise L0s and L1. */
98 RCBA32(RCBA_LCAP) |= (3 << 10);
99 /* Enable L0s and L1. */
100 RCBA32(RCBA_LCTL) |= (3 << 0);
101 } else {
102 /* Enable DMI power savings. */
103 RCBA32(RCBA_DMC) |= (1 << 19);
104 /* Advertise L0s only. */
105 RCBA32(RCBA_LCAP) = (RCBA32(RCBA_LCAP) & ~(3<<10)) | (1<<10);
106 /* Enable L0s only. */
107 RCBA32(RCBA_LCTL) = (RCBA32(RCBA_LCTL) & ~(3<< 0)) | (1<< 0);
108 }
109}
110
111/* Should be called after VC1 has been enabled on both sides. */
112void i82801ix_dmi_poll_vc1(void)
113{
114 int timeout;
115
116 timeout = 0x7ffff;
117 printk(BIOS_DEBUG, "ICH9 waits for VC1 negotiation... ");
118 while ((RCBA32(RCBA_V1STS) & (1 << 1)) && --timeout) {}
119 if (!timeout)
120 printk(BIOS_DEBUG, "timeout!\n");
121 else
122 printk(BIOS_DEBUG, "done.\n");
123
124 /* Check for x2 DMI link. */
125 if (((RCBA16(RCBA_LSTS) >> 4) & 0x3f) == 2) {
126 printk(BIOS_DEBUG, "x2 DMI link detected.\n");
127 RCBA32(0x2024) = (RCBA32(0x2024) & ~(7 << 21)) | (3 << 21);
128 RCBA16(0x20c4) |= (1 << 15);
129 RCBA16(0x20e4) |= (1 << 15);
130 /* TODO: Maybe we have to save and
131 restore these settings across S3. */
132 }
133
134 timeout = 0x7ffff;
135 printk(BIOS_DEBUG, "ICH9 waits for port arbitration table update... ");
136 while ((RCBA32(RCBA_V1STS) & (1 << 0)) && --timeout) {}
137 if (!timeout)
138 printk(BIOS_DEBUG, "timeout!\n");
139 else
140 printk(BIOS_DEBUG, "done.\n");
141}