From 50001b80f54c3d1cdd926102c68d33e549541205 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 11 Aug 2015 17:47:48 -0500 Subject: 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 Reviewed-on: http://review.coreboot.org/12042 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/cpu/amd/family_10h-family_15h/init_cpus.c | 61 +++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'src/cpu') 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"); } -- cgit v1.2.3