1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/pci_def.h>
4 #include <console/console.h>
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,
26 void i82801ix_dmi_setup(void)
31 RCBA32(RCBA_V1CAP
) = (RCBA32(RCBA_V1CAP
) & ~(0x7f<<16)) | (0x12<<16);
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);
40 /* VC1 setup for isochronous transfers: */
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. */
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);
59 RCBA32(RCBA_V1CTL
) |= (1 << 31);
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
;
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. */
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);
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);
94 /* Should be called after VC1 has been enabled on both sides. */
95 void i82801ix_dmi_poll_vc1(void)
100 printk(BIOS_DEBUG
, "ICH9 waits for VC1 negotiation... ");
101 while ((RCBA32(RCBA_V1STS
) & (1 << 1)) && --timeout
) {}
103 printk(BIOS_DEBUG
, "timeout!\n");
105 printk(BIOS_DEBUG
, "done.\n");
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. */
118 printk(BIOS_DEBUG
, "ICH9 waits for port arbitration table update... ");
119 while ((RCBA32(RCBA_V1STS
) & (1 << 0)) && --timeout
) {}
121 printk(BIOS_DEBUG
, "timeout!\n");
123 printk(BIOS_DEBUG
, "done.\n");