coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
dmi_setup.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/pci_def.h>
4 #include <console/console.h>
5 #include "i82801ix.h"
6 
7 /* VC1 Port Arbitration Table */
8 static const u8 vc1_pat[] = {
9  0x0f, 0x00, 0x00, 0x00,
10  0x00, 0x00, 0x0f, 0x00,
11  0x00, 0x00, 0x00, 0x00,
12  0xf0, 0x00, 0x00, 0x00,
13  0x00, 0x00, 0x00, 0x0f,
14  0x00, 0x00, 0x00, 0x00,
15  0x00, 0xf0, 0x00, 0x00,
16  0x00, 0x00, 0x00, 0x00,
17  0x0f, 0x00, 0x00, 0x00,
18  0x00, 0x00, 0x0f, 0x00,
19  0x00, 0x00, 0x00, 0x00,
20  0xf0, 0x00, 0x00, 0x00,
21  0x00, 0x00, 0x00, 0x0f,
22  0x00, 0x00, 0x00, 0x00,
23  0x00, 0xf0, 0x00, 0x00,
24  0x00, 0x00, 0x00, 0x00,
25 };
27 {
28  int i;
29  u32 reg32;
30 
31  RCBA32(RCBA_V1CAP) = (RCBA32(RCBA_V1CAP) & ~(0x7f<<16)) | (0x12<<16);
32 
33  /* NB: other CIRs are handled in i82801ix_early_settings(). */
34  RCBA32(RCBA_CIR1) = 0x00109000;
35  RCBA16(RCBA_CIR3) = 0x060b;
36  RCBA32(RCBA_CIR2) = 0x86000040;
37  RCBA8(RCBA_BCR) = 0x45;
38  RCBA32(RCBA_CIR6) &= ~(1 << 7);
39 
40  /* VC1 setup for isochronous transfers: */
41 
42  /* Set VC1 virtual channel id to 1. */
43  RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7 << 24)) | (0x1 << 24);
44  /* Enable TC7 traffic on VC1. */
45  RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7f << 1)) | (1 << 7);
46  /* Disable TC7-TC1 traffic on VC0. */
47  RCBA32(RCBA_V0CTL) &= ~(0x7f << 1);
48  /* TC7-TC1 traffic on PCIe root ports will be disabled in pci driver. */
49 
50  /* Set table type to time-based WRR. */
51  RCBA32(RCBA_V1CTL) = (RCBA32(RCBA_V1CTL) & ~(0x7 << 17)) | (0x4 << 17);
52  /* Program port arbitration table. */
53  for (i = 0; i < sizeof(vc1_pat); ++i)
54  RCBA8(RCBA_PAT + i) = vc1_pat[i];
55  /* Load port arbitration table. */
56  RCBA32(RCBA_V1CTL) |= (1 << 16);
57 
58  /* Enable VC1. */
59  RCBA32(RCBA_V1CTL) |= (1 << 31);
60 
61  /* Setup RCRB: */
62 
63  /* Set component id to 2 for southbridge, northbridge has id 1. */
64  RCBA8(RCBA_ESD + 2) = 2;
65  /* Set target port number and target component id of the northbridge. */
66  RCBA8(RCBA_ULD + 3) = 1;
67  RCBA8(RCBA_ULD + 2) = 1;
68  /* Set target rcrb base address, i.e. DMIBAR. */
69  RCBA32(RCBA_ULBA) = (uintptr_t)CONFIG_FIXED_DMIBAR_MMIO_BASE;
70 
71  /* Enable ASPM. */
72  if (LPC_IS_MOBILE(PCI_DEV(0, 0x1f, 0))) {
73  reg32 = RCBA32(RCBA_DMC);
74  /* Enable mobile specific power saving (set this first). */
75  reg32 = (reg32 & ~(3 << 10)) | (1 << 10);
76  RCBA32(RCBA_DMC) = reg32;
77  /* Enable DMI power savings. */
78  reg32 |= (1 << 19);
79  RCBA32(RCBA_DMC) = reg32;
80  /* Advertise L0s and L1. */
81  RCBA32(RCBA_LCAP) |= (3 << 10);
82  /* Enable L0s and L1. */
83  RCBA32(RCBA_LCTL) |= (3 << 0);
84  } else {
85  /* Enable DMI power savings. */
86  RCBA32(RCBA_DMC) |= (1 << 19);
87  /* Advertise L0s only. */
88  RCBA32(RCBA_LCAP) = (RCBA32(RCBA_LCAP) & ~(3<<10)) | (1<<10);
89  /* Enable L0s only. */
90  RCBA32(RCBA_LCTL) = (RCBA32(RCBA_LCTL) & ~(3<< 0)) | (1<< 0);
91  }
92 }
93 
94 /* Should be called after VC1 has been enabled on both sides. */
96 {
97  int timeout;
98 
99  timeout = 0x7ffff;
100  printk(BIOS_DEBUG, "ICH9 waits for VC1 negotiation... ");
101  while ((RCBA32(RCBA_V1STS) & (1 << 1)) && --timeout) {}
102  if (!timeout)
103  printk(BIOS_DEBUG, "timeout!\n");
104  else
105  printk(BIOS_DEBUG, "done.\n");
106 
107  /* Check for x2 DMI link. */
108  if (((RCBA16(RCBA_LSTS) >> 4) & 0x3f) == 2) {
109  printk(BIOS_DEBUG, "x2 DMI link detected.\n");
110  RCBA32(0x2024) = (RCBA32(0x2024) & ~(7 << 21)) | (3 << 21);
111  RCBA16(0x20c4) |= (1 << 15);
112  RCBA16(0x20e4) |= (1 << 15);
113  /* TODO: Maybe we have to save and
114  restore these settings across S3. */
115  }
116 
117  timeout = 0x7ffff;
118  printk(BIOS_DEBUG, "ICH9 waits for port arbitration table update... ");
119  while ((RCBA32(RCBA_V1STS) & (1 << 0)) && --timeout) {}
120  if (!timeout)
121  printk(BIOS_DEBUG, "timeout!\n");
122  else
123  printk(BIOS_DEBUG, "done.\n");
124 }
#define printk(level,...)
Definition: stdlib.h:16
void i82801ix_dmi_setup(void)
Definition: dmi_setup.c:26
void i82801ix_dmi_poll_vc1(void)
Definition: dmi_setup.c:95
static const u8 vc1_pat[]
Definition: dmi_setup.c:8
#define RCBA_V0CTL
Definition: i82801ix.h:95
#define RCBA_LCTL
Definition: i82801ix.h:105
#define RCBA_BCR
Definition: i82801ix.h:109
#define LPC_IS_MOBILE(dev)
Definition: i82801ix.h:159
#define RCBA_ULD
Definition: i82801ix.h:102
#define RCBA_CIR1
Definition: i82801ix.h:100
#define RCBA_DMC
Definition: i82801ix.h:114
#define RCBA_LCAP
Definition: i82801ix.h:104
#define RCBA_ULBA
Definition: i82801ix.h:103
#define RCBA_CIR6
Definition: i82801ix.h:115
#define RCBA_CIR2
Definition: i82801ix.h:107
#define RCBA_PAT
Definition: i82801ix.h:99
#define RCBA_V1CTL
Definition: i82801ix.h:97
#define RCBA_V1CAP
Definition: i82801ix.h:96
#define RCBA_ESD
Definition: i82801ix.h:101
#define RCBA_LSTS
Definition: i82801ix.h:106
#define RCBA_CIR3
Definition: i82801ix.h:108
#define RCBA_V1STS
Definition: i82801ix.h:98
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
#define RCBA16(x)
Definition: rcba.h:13
#define RCBA8(x)
Definition: rcba.h:12
#define RCBA32(x)
Definition: rcba.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45