northbridge/amd/amdht: Add isochronous setup support

The coherent fabric on all Family 10h/15h devices supports
isochronous mode, which is required for IOMMU operation.

Add initial support for isochronous operation.

Change-Id: Idd7c9b94a65f856b0059e1d45f8719d9475771b6
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/12042
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Timothy Pearson
2015-08-11 17:47:48 -05:00
committed by Martin Roth
parent 68130f506d
commit 50001b80f5
5 changed files with 129 additions and 4 deletions

View File

@@ -1666,6 +1666,67 @@ static void cpuSetAMDPCI(u8 node)
pci_write_config32(NODE_PCI(node, 3), 0x140, dword);
}
uint8_t link;
uint8_t isochronous;
uint8_t isochronous_link_present;
/* Set up isochronous buffers if needed */
isochronous_link_present = 0;
if (revision & AMD_FAM15_ALL) {
for (link = 0; link < 4; link++) {
if (AMD_CpuFindCapability(node, link, &offset)) {
isochronous = (pci_read_config32(NODE_PCI(node, 0), (link * 0x20) + 0x84) >> 12) & 0x1;
if (isochronous)
isochronous_link_present = 1;
}
}
}
uint8_t free_tok;
uint8_t up_rsp_cbc;
uint8_t isoc_preq_cbc;
uint8_t isoc_preq_tok;
uint8_t xbar_to_sri_free_list_cbc;
if (isochronous_link_present) {
/* Adjust buffer counts */
dword = pci_read_config32(NODE_PCI(node, 3), 0x70);
isoc_preq_cbc = (dword >> 24) & 0x7;
up_rsp_cbc = (dword >> 16) & 0x7;
up_rsp_cbc--;
isoc_preq_cbc++;
dword &= ~(0x7 << 24); /* IsocPreqCBC = isoc_preq_cbc */
dword |= ((isoc_preq_cbc & 0x7) << 24);
dword &= ~(0x7 << 16); /* UpRspCBC = up_rsp_cbc */
dword |= ((up_rsp_cbc & 0x7) << 16);
pci_write_config32(NODE_PCI(node, 3), 0x70, dword);
dword = pci_read_config32(NODE_PCI(node, 3), 0x74);
isoc_preq_cbc = (dword >> 24) & 0x7;
isoc_preq_cbc++;
dword &= ~(0x7 << 24); /* IsocPreqCBC = isoc_preq_cbc */
dword |= (isoc_preq_cbc & 0x7) << 24;
pci_write_config32(NODE_PCI(node, 3), 0x74, dword);
dword = pci_read_config32(NODE_PCI(node, 3), 0x7c);
xbar_to_sri_free_list_cbc = dword & 0x1f;
xbar_to_sri_free_list_cbc--;
dword &= ~0x1f; /* Xbar2SriFreeListCBC = xbar_to_sri_free_list_cbc */
dword |= xbar_to_sri_free_list_cbc & 0x1f;
pci_write_config32(NODE_PCI(node, 3), 0x7c, dword);
dword = pci_read_config32(NODE_PCI(node, 3), 0x140);
free_tok = (dword >> 20) & 0xf;
isoc_preq_tok = (dword >> 14) & 0x3;
free_tok--;
isoc_preq_tok++;
dword &= ~(0xf << 20); /* FreeTok = free_tok */
dword |= ((free_tok & 0xf) << 20);
dword &= ~(0x3 << 14); /* IsocPreqTok = isoc_preq_tok */
dword |= ((isoc_preq_tok & 0x3) << 14);
pci_write_config32(NODE_PCI(node, 3), 0x140, dword);
}
printk(BIOS_DEBUG, " done\n");
}