cpu/amd/family_10h-family_15h: Set up link XCS token counts on Family 15h

Change-Id: I4cf6549234041c395a18a89332d95f20a596fc3e
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/12033
Tested-by: build bot (Jenkins)
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
Timothy Pearson 2015-08-07 23:59:17 -05:00 committed by Stefan Reinauer
parent 99f80422f6
commit 71b8f01b62
1 changed files with 304 additions and 0 deletions

View File

@ -1054,6 +1054,12 @@ static void cpuSetAMDPCI(u8 node)
uint32_t dword;
uint64_t revision;
/* FIXME
* This should be configurable
*/
uint8_t sockets = 2;
uint8_t sockets_populated = 2;
printk(BIOS_DEBUG, "cpuSetAMDPCI %02d", node);
revision = mctGetLogicalCPUID(node);
@ -1160,6 +1166,15 @@ static void cpuSetAMDPCI(u8 node)
uint8_t compute_unit_count = 0;
uint8_t compute_unit_buffer_count;
uint32_t f3xe8;
uint8_t dual_node = 0;
f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8);
/* Check for dual node capability */
if (f3xe8 & 0x20000000)
dual_node = 1;
/* Determine the number of active compute units on this node */
f5x80 = pci_read_config32(NODE_PCI(node, 5), 0x80);
cu_enabled = f5x80 & 0xf;
@ -1185,6 +1200,295 @@ static void cpuSetAMDPCI(u8 node)
dword &= ~(0x1f << 4); /* L3FreeListCBC = compute_unit_buffer_count */
dword |= (compute_unit_buffer_count << 4);
pci_write_config32(NODE_PCI(node, 3), 0x1a0, dword);
/* Set up the Link to XCS Token Counts */
uint8_t isoc_rsp_tok_1;
uint8_t isoc_preq_tok_1;
uint8_t isoc_req_tok_1;
uint8_t probe_tok_1;
uint8_t rsp_tok_1;
uint8_t preq_tok_1;
uint8_t req_tok_1;
uint8_t isoc_rsp_tok_0;
uint8_t isoc_preq_tok_0;
uint8_t isoc_req_tok_0;
uint8_t free_tokens;
uint8_t probe_tok_0;
uint8_t rsp_tok_0;
uint8_t preq_tok_0;
uint8_t req_tok_0;
uint8_t link;
uint8_t ganged;
uint8_t iolink;
uint8_t probe_filter_enabled = !!dual_node;
for (link = 0; link < 4; link++) {
if (AMD_CpuFindCapability(node, link, &offset)) {
ganged = !!(pci_read_config32(NODE_PCI(node, 0), (link << 2) + 0x170) & 0x1);
iolink = (AMD_checkLinkType(node, link, offset) & HTPHY_LINKTYPE_NONCOHERENT);
/* Set defaults */
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = !ganged;
rsp_tok_1 = !ganged;
preq_tok_1 = !ganged;
req_tok_1 = !ganged;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 0;
free_tokens = 0;
probe_tok_0 = ((ganged)?2:1);
rsp_tok_0 = ((ganged)?2:1);
preq_tok_0 = ((ganged)?2:1);
req_tok_0 = ((ganged)?2:1);
if (!iolink && ganged) {
if (!dual_node) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 3;
probe_tok_0 = 2;
rsp_tok_0 = 2;
preq_tok_0 = 2;
req_tok_0 = 2;
} else {
if ((sockets == 1)
|| ((sockets == 2) && (sockets_populated == 1))) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 2;
rsp_tok_0 = 2;
preq_tok_0 = 2;
req_tok_0 = 2;
} else if (((sockets == 2) && (sockets_populated == 2))
|| ((sockets == 4) && (sockets_populated == 2))) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 1;
rsp_tok_0 = 2;
preq_tok_0 = 2;
req_tok_0 = 2;
} else if ((sockets == 4) && (sockets_populated == 4)) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 2;
rsp_tok_0 = 1;
preq_tok_0 = 1;
req_tok_0 = 2;
}
}
} else if (!iolink && !ganged) {
if ((sockets == 1)
|| ((sockets == 2) && (sockets_populated == 1))) {
if (probe_filter_enabled) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 1;
rsp_tok_1 = 1;
preq_tok_1 = 1;
req_tok_1 = 1;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 1;
rsp_tok_0 = 2;
preq_tok_0 = 1;
req_tok_0 = 1;
} else {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 1;
rsp_tok_1 = 1;
preq_tok_1 = 1;
req_tok_1 = 1;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 1;
rsp_tok_0 = 1;
preq_tok_0 = 1;
req_tok_0 = 1;
}
} else if ((sockets == 2) && (sockets_populated == 2)) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 1;
probe_tok_1 = 1;
rsp_tok_1 = 1;
preq_tok_1 = 1;
req_tok_1 = 1;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 2;
probe_tok_0 = 1;
rsp_tok_0 = 1;
preq_tok_0 = 1;
req_tok_0 = 1;
} else if ((sockets == 4) && (sockets_populated == 2)) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 1;
probe_tok_1 = 1;
rsp_tok_1 = 1;
preq_tok_1 = 1;
req_tok_1 = 1;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 4;
probe_tok_0 = 1;
rsp_tok_0 = 1;
preq_tok_0 = 1;
req_tok_0 = 1;
} else if ((sockets == 4) && (sockets_populated == 4)) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 1;
probe_tok_1 = 1;
rsp_tok_1 = 1;
preq_tok_1 = 1;
req_tok_1 = 1;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 1;
rsp_tok_0 = 1;
preq_tok_0 = 1;
req_tok_0 = 1;
}
} else if (iolink && ganged) {
if (!dual_node) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 3;
probe_tok_0 = 0;
rsp_tok_0 = 2;
preq_tok_0 = 2;
req_tok_0 = 2;
} else if ((sockets == 1)
|| (sockets == 2)
|| ((sockets == 4) && (sockets_populated == 2))) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 1;
free_tokens = 0;
probe_tok_0 = 0;
rsp_tok_0 = 2;
preq_tok_0 = 2;
req_tok_0 = 2;
} else if ((sockets == 4) && (sockets_populated == 4)) {
isoc_rsp_tok_1 = 0;
isoc_preq_tok_1 = 0;
isoc_req_tok_1 = 0;
probe_tok_1 = 0;
rsp_tok_1 = 0;
preq_tok_1 = 0;
req_tok_1 = 0;
isoc_rsp_tok_0 = 0;
isoc_preq_tok_0 = 0;
isoc_req_tok_0 = 2;
free_tokens = 0;
probe_tok_0 = 2;
rsp_tok_0 = 2;
preq_tok_0 = 2;
req_tok_0 = 2;
}
}
dword = pci_read_config32(NODE_PCI(node, 3), (link << 2) + 0x148);
dword &= ~(0x3 << 30); /* FreeTok[3:2] = free_tokens[3:2] */
dword |= (((free_tokens >> 2) & 0x3) << 30);
dword &= ~(0x1 << 28); /* IsocRspTok1 = isoc_rsp_tok_1 */
dword |= (((isoc_rsp_tok_1) & 0x1) << 28);
dword &= ~(0x1 << 26); /* IsocPreqTok1 = isoc_preq_tok_1 */
dword |= (((isoc_preq_tok_1) & 0x1) << 26);
dword &= ~(0x1 << 24); /* IsocReqTok1 = isoc_req_tok_1 */
dword |= (((isoc_req_tok_1) & 0x1) << 24);
dword &= ~(0x3 << 22); /* ProbeTok1 = probe_tok_1 */
dword |= (((probe_tok_1) & 0x3) << 22);
dword &= ~(0x3 << 20); /* RspTok1 = rsp_tok_1 */
dword |= (((rsp_tok_1) & 0x3) << 20);
dword &= ~(0x3 << 18); /* PReqTok1 = preq_tok_1 */
dword |= (((preq_tok_1) & 0x3) << 18);
dword &= ~(0x3 << 16); /* ReqTok1 = req_tok_1 */
dword |= (((req_tok_1) & 0x3) << 16);
dword &= ~(0x3 << 14); /* FreeTok[1:0] = free_tokens[1:0] */
dword |= (((free_tokens) & 0x3) << 14);
dword &= ~(0x3 << 12); /* IsocRspTok0 = isoc_rsp_tok_0 */
dword |= (((isoc_rsp_tok_0) & 0x3) << 12);
dword &= ~(0x3 << 10); /* IsocPreqTok0 = isoc_preq_tok_0 */
dword |= (((isoc_preq_tok_0) & 0x3) << 10);
dword &= ~(0x3 << 8); /* IsocReqTok0 = isoc_req_tok_0 */
dword |= (((isoc_req_tok_0) & 0x3) << 8);
dword &= ~(0x3 << 6); /* ProbeTok0 = probe_tok_0 */
dword |= (((probe_tok_0) & 0x3) << 6);
dword &= ~(0x3 << 4); /* RspTok0 = rsp_tok_0 */
dword |= (((rsp_tok_0) & 0x3) << 4);
dword &= ~(0x3 << 2); /* PReqTok0 = preq_tok_0 */
dword |= (((preq_tok_0) & 0x3) << 2);
dword &= ~(0x3 << 0); /* ReqTok0 = req_tok_0 */
dword |= (((req_tok_0) & 0x3) << 0);
pci_write_config32(NODE_PCI(node, 3), (link << 2) + 0x148, dword);
}
}
}
printk(BIOS_DEBUG, " done\n");