• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 };
i82801ix_dmi_setup(void)26 void i82801ix_dmi_setup(void)
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. */
i82801ix_dmi_poll_vc1(void)95 void i82801ix_dmi_poll_vc1(void)
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 }
125