summaryrefslogtreecommitdiff
path: root/src/cpu/amd
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-08-11 17:47:48 -0500
committerMartin Roth <martinroth@google.com>2015-11-24 19:28:00 +0100
commit50001b80f54c3d1cdd926102c68d33e549541205 (patch)
tree6c789e9040e25f31ed5336a95f59da69ca0ec484 /src/cpu/amd
parent68130f506df5c77107ece8d71aa45b598be77b45 (diff)
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>
Diffstat (limited to 'src/cpu/amd')
-rw-r--r--src/cpu/amd/family_10h-family_15h/init_cpus.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c
index da458883d3..635f35787e 100644
--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c
+++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c
@@ -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");
}