intelblocks/pcie: Correct mapping between LCAP port and coreboot index
coreboot uses port index which is 0 based for all PCIe root ports. In case of PCIe remapping logic, coreboot reads LCAP register from PCIe configuration space which contains port number (mostly 1 based). This assumption might not be true for all the ports in coreboot. TBT's LCAP registers are returning port index which are based on 2. coreboot's PCIe remapping logic returns port index based on index 1. This patch adds variable to pcie_rp_config to pass lcap_port_base to the pcie remapping function, so coreboot can map any n-based LCAP encoding to 0-based indexing scheme. This patch updates correct lcap_port_base variable for all PCIe root ports for all SOCs, so that function returns correct 0-based index from LCAP port number. BUG=b:210933428 BRANCH=None TEST=Check if code compiles for all ADL boards Change-Id: I7f9c3c8e753b982e2ede1a41bf87d6355b82da0f Signed-off-by: MAULIK V VAGHELA <maulik.v.vaghela@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/61936 Reviewed-by: Subrata Banik <subratabanik@google.com> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: EricR Lai <ericr_lai@compal.corp-partner.google.com> Reviewed-by: Nico Huber <nico.h@gmx.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
811aab3586
commit
d9c5b14f1e
|
@ -9,14 +9,14 @@
|
||||||
#define CPU_CPIE_VW_IDX_BASE 24
|
#define CPU_CPIE_VW_IDX_BASE 24
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_m_rp_groups[] = {
|
static const struct pcie_rp_group pch_m_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 2 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 2, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,14 +35,14 @@ const struct pcie_rp_group *get_pch_pcie_rp_table(void)
|
||||||
* RP3: PEG62 : 0:6:2 : x4 CPU Slot
|
* RP3: PEG62 : 0:6:2 : x4 CPU Slot
|
||||||
*/
|
*/
|
||||||
static const struct pcie_rp_group cpu_rp_groups[] = {
|
static const struct pcie_rp_group cpu_rp_groups[] = {
|
||||||
{ .slot = SA_DEV_SLOT_CPU_6, .start = 0, .count = 1 },
|
{ .slot = SA_DEV_SLOT_CPU_6, .start = 0, .count = 1, .lcap_port_base = 1 },
|
||||||
{ .slot = SA_DEV_SLOT_CPU_1, .start = 0, .count = 1 },
|
{ .slot = SA_DEV_SLOT_CPU_1, .start = 0, .count = 1, .lcap_port_base = 1 },
|
||||||
{ .slot = SA_DEV_SLOT_CPU_6, .start = 2, .count = 1 },
|
{ .slot = SA_DEV_SLOT_CPU_6, .start = 2, .count = 1, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pcie_rp_group cpu_m_rp_groups[] = {
|
static const struct pcie_rp_group cpu_m_rp_groups[] = {
|
||||||
{ .slot = SA_DEV_SLOT_CPU_6, .start = 0, .count = 1 },
|
{ .slot = SA_DEV_SLOT_CPU_6, .start = 0, .count = 1, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,8 +61,14 @@ const struct pcie_rp_group *get_cpu_pcie_rp_table(void)
|
||||||
return cpu_rp_groups;
|
return cpu_rp_groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TBT's LCAP registers are returning port index which starts from 2 (Usually for other PCIe
|
||||||
|
* root ports index starts from 1). Thus keeping lcap_port_base 2 for TBT, so that coreboot's
|
||||||
|
* PCIe remapping logic can return correct index (0-based)
|
||||||
|
*/
|
||||||
|
|
||||||
static const struct pcie_rp_group tbt_rp_groups[] = {
|
static const struct pcie_rp_group tbt_rp_groups[] = {
|
||||||
{ .slot = SA_DEV_SLOT_TBT, .count = CONFIG_MAX_TBT_ROOT_PORTS},
|
{ .slot = SA_DEV_SLOT_TBT, .count = CONFIG_MAX_TBT_ROOT_PORTS, .lcap_port_base = 2 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,15 +18,15 @@
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_h_rp_groups[] = {
|
static const struct pcie_rp_group pch_h_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_2, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_2, .count = 8, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,17 @@ struct pcie_rp_config {
|
||||||
* in case the root port numbers are not contiguous within the slot.
|
* in case the root port numbers are not contiguous within the slot.
|
||||||
* `count` is the number of functions within the group starting with the `start`
|
* `count` is the number of functions within the group starting with the `start`
|
||||||
* function number.
|
* function number.
|
||||||
|
* `lcap_port_base` is the starting index of physical port as described in LCAP
|
||||||
|
* register in PCIe config space. coreboot always uses 0 based indexing while
|
||||||
|
* referring to the PCIe port but LCAP registers uses 1-based indexing in
|
||||||
|
* most of the cases. Remapping logic needs to correctly map LCAP port number
|
||||||
|
* (1-based or n-based) to coreboot indexing (0-based).
|
||||||
*/
|
*/
|
||||||
struct pcie_rp_group {
|
struct pcie_rp_group {
|
||||||
unsigned int slot;
|
unsigned int slot;
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
unsigned int lcap_port_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned int rp_start_fn(const struct pcie_rp_group *group)
|
static inline unsigned int rp_start_fn(const struct pcie_rp_group *group)
|
||||||
|
|
|
@ -31,20 +31,25 @@ static int pcie_rp_original_idx(
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t lcap = pci_s_read_config32(dev, clist + PCI_EXP_LNKCAP);
|
const uint32_t lcap = pci_s_read_config32(dev, clist + PCI_EXP_LNKCAP);
|
||||||
/* Read 1-based absolute port number. This reflects the numbering
|
|
||||||
scheme that Intel uses in their documentation and what we use
|
/* Read n-based absolute port number from LCAP register.
|
||||||
as index (0-based, though) in our mapping. */
|
This reflects the numbering scheme that Intel uses in their
|
||||||
|
documentation and what we use as index (0-based, though) in
|
||||||
|
our mapping. */
|
||||||
const unsigned int port_num = (lcap & PCI_EXP_LNKCAP_PORT) >> 24;
|
const unsigned int port_num = (lcap & PCI_EXP_LNKCAP_PORT) >> 24;
|
||||||
|
|
||||||
/* `port_num` is 1-based, `offset` is 0-based. */
|
/* Subtract lcap_port_base from port_num to get 0-based index */
|
||||||
if (port_num <= offset || port_num > offset + group->count) {
|
const unsigned int port_idx = port_num - group->lcap_port_base;
|
||||||
|
|
||||||
|
/* Check if port_idx (0-based) is out of bounds */
|
||||||
|
if (port_idx < offset || port_idx >= offset + group->count) {
|
||||||
printk(BIOS_WARNING, "%s: Unexpected root-port number '%u'"
|
printk(BIOS_WARNING, "%s: Unexpected root-port number '%u'"
|
||||||
" at PCI: 00:%02x.%x, ignoring.\n",
|
" at PCI: 00:%02x.%x, ignoring.\n",
|
||||||
__func__, port_num, group->slot, PCI_FUNC(PCI_DEV2DEVFN(dev)));
|
__func__, port_num, group->slot, PCI_FUNC(PCI_DEV2DEVFN(dev)));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return port_num - 1;
|
return port_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan actual PCI config space to reconstruct current mapping */
|
/* Scan actual PCI config space to reconstruct current mapping */
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <soc/soc_chip.h>
|
#include <soc/soc_chip.h>
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_rp_groups[] = {
|
static const struct pcie_rp_group pch_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 7 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 7, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <soc/soc_chip.h>
|
#include <soc/soc_chip.h>
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_rp_groups[] = {
|
static const struct pcie_rp_group pch_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,18 +34,18 @@
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_h_rp_groups[] = {
|
static const struct pcie_rp_group pch_h_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8, .lcap_port_base = 1 },
|
||||||
/* Sunrise Point PCH-H actually only has 4 ports in the
|
/* Sunrise Point PCH-H actually only has 4 ports in the
|
||||||
third group. But that would require a runtime check
|
third group. But that would require a runtime check
|
||||||
and probing 4 non-existent ports shouldn't hurt. */
|
and probing 4 non-existent ports shouldn't hurt. */
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_2, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_2, .count = 8, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,21 +7,21 @@
|
||||||
#define CPU_CPIE_VW_IDX_BASE 24
|
#define CPU_CPIE_VW_IDX_BASE 24
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pcie_rp_group pch_h_rp_groups[] = {
|
static const struct pcie_rp_group pch_h_rp_groups[] = {
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 8, .lcap_port_base = 1 },
|
||||||
{ .slot = PCH_DEV_SLOT_PCIE_2, .count = 8 },
|
{ .slot = PCH_DEV_SLOT_PCIE_2, .count = 8, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pcie_rp_group cpu_rp_groups[] = {
|
static const struct pcie_rp_group cpu_rp_groups[] = {
|
||||||
{ .slot = SA_DEV_SLOT_PEG, .start = 0, .count = 3 },
|
{ .slot = SA_DEV_SLOT_PEG, .start = 0, .count = 3, .lcap_port_base = 1 },
|
||||||
{ .slot = SA_DEV_SLOT_CPU_PCIE, .start = 0, .count = 1 },
|
{ .slot = SA_DEV_SLOT_CPU_PCIE, .start = 0, .count = 1, .lcap_port_base = 1 },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue