1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/amd_pci_util.h>
#include <console/console.h>
#include <device/pci_def.h>
#include <types.h>
enum pcie_swizzle_pin {
PIN_A,
PIN_B,
PIN_C,
PIN_D,
};
static const uint8_t pcie_swizzle_table[][4] = {
{PIN_A, PIN_B, PIN_C, PIN_D},
{PIN_B, PIN_C, PIN_D, PIN_A},
{PIN_C, PIN_D, PIN_A, PIN_B},
{PIN_D, PIN_A, PIN_B, PIN_C},
};
const struct pci_routing_info *get_pci_routing_info(unsigned int devfn)
{
const struct pci_routing_info *routing_info;
size_t entries = 0;
routing_info = get_pci_routing_table(&entries);
if (!routing_info || !entries)
return NULL;
for (size_t i = 0; i < entries; ++i, ++routing_info)
if (routing_info->devfn == devfn)
return routing_info;
printk(BIOS_ERR, "Failed to find PCIe routing info for dev: %#x, fn: %#x\n",
PCI_SLOT(devfn), PCI_FUNC(devfn));
return NULL;
}
unsigned int pci_calculate_irq(const struct pci_routing_info *routing_info,
unsigned int pin)
{
unsigned int irq;
if (routing_info->swizzle >= ARRAY_SIZE(pcie_swizzle_table))
die("%s: swizzle %u out of bounds\n", __func__, routing_info->swizzle);
if (pin >= ARRAY_SIZE(pcie_swizzle_table[routing_info->swizzle]))
die("%s: pin %u out of bounds\n", __func__, pin);
irq = routing_info->group * 4;
irq += pcie_swizzle_table[routing_info->swizzle][pin];
return irq;
}
|