MAINTAINERS: Add Yuchi and Vasiliy for Intel Atom Snow Ridge SoC
[coreboot.git] / src / soc / intel / snowridge / sriov.c
blob61f9c7c8b751139bcdc62de7c6a7f8843da5d892
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/bsd/helpers.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci_def.h>
7 #include <device/pciexp.h>
8 #include <device/resource.h>
9 #include <lib.h>
11 #include "ramstage.h"
13 void pciexp_vf_read_resources(struct device *dev)
15 uint32_t sriov_cap_offset, supported_page_size, system_page_size;
16 uint16_t num_vfs, index;
17 int align;
18 struct resource *resource;
20 sriov_cap_offset = pciexp_find_extended_cap(dev, PCIE_EXT_CAP_SRIOV_ID, 0);
21 if (sriov_cap_offset == 0) {
22 printk(BIOS_DEBUG, "No SRIOV capability for %s!\n", dev_path(dev));
23 return;
26 printk(BIOS_DEBUG, "%s SRIOV capability found at offset 0x%x\n", dev_path(dev),
27 sriov_cap_offset);
29 supported_page_size = pci_read_config32(
30 dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_SUPPORTED_PAGE_SIZE);
31 if (supported_page_size == 0) {
32 printk(BIOS_DEBUG, "No supported page size for %s!\n", dev_path(dev));
33 return;
36 system_page_size =
37 pci_read_config32(dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_SYSTEM_PAGE_SIZE);
38 if ((system_page_size & supported_page_size) == 0) {
39 printk(BIOS_ERR, "Unsupportted system page size 0x%08x for %s!\n",
40 system_page_size, dev_path(dev));
41 return;
44 if (popcnt(system_page_size) != 1) {
45 printk(BIOS_ERR, "More than 1 bit is set in system page size for %s!\n",
46 dev_path(dev));
47 return;
50 num_vfs = pci_read_config16(dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_TOTAL_VFS);
52 /**
53 * If bit `n` is set, the VFs are required to support a page size of 2 ^ (n + 12).
55 align = __ffs(system_page_size) + 12;
57 for (index = PCIE_EXT_CAP_SRIOV_VF_BAR0; index <= PCIE_EXT_CAP_SRIOV_VF_BAR5;
58 index += 4) {
59 resource = pci_get_resource(dev, sriov_cap_offset + index);
60 if (resource->flags == 0)
61 continue;
63 printk(BIOS_DEBUG, "%s SRIOV BAR at offset 0x%x\n", dev_path(dev),
64 sriov_cap_offset + index);
66 /**
67 * Section 9.3.3.13 of PCIe Base Specification 6.2.
69 resource->align = MAX(resource->align, align);
70 resource->gran = MAX(resource->gran, align);
71 resource->size = 1 << resource->gran;
73 resource->size *= num_vfs;
75 /**
76 * Allocate above 4G to avoid exhausting MMIO32 space.
78 if (resource->size >= 16 * MiB)
79 resource->flags |= IORESOURCE_ABOVE_4G;
81 printk(BIOS_DEBUG, "%s SRIOV BAR size 0x%llx, flags 0x%lx\n", dev_path(dev),
82 resource->size, resource->flags);
84 if (resource->flags & IORESOURCE_PCI64)
85 index += 4;
89 void pciexp_pf_read_resources(struct device *dev)
91 uint16_t index;
92 struct resource *resource;
94 printk(BIOS_SPEW, "Reading resource: %s idx %02x\n", dev_path(dev), PCI_BASE_ADDRESS_0);
96 for (index = PCI_BASE_ADDRESS_0; index < PCI_BASE_ADDRESS_0 + (6 << 2);) {
97 resource = pci_get_resource(dev, index);
98 /**
99 * Allocate above 4G to avoid exhausting MMIO32 space.
101 if (resource->size >= 16 * MiB)
102 resource->flags |= IORESOURCE_ABOVE_4G;
104 index += (resource->flags & IORESOURCE_PCI64) ? 8 : 4;
107 pciexp_vf_read_resources(dev);
109 compact_resources(dev);