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>
129 lines
3.3 KiB
C
129 lines
3.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <device/device.h>
|
|
#include <intelblocks/pcie_rp.h>
|
|
#include <soc/cpu.h>
|
|
#include <soc/pci_devs.h>
|
|
#include <soc/pcie.h>
|
|
|
|
#define CPU_CPIE_VW_IDX_BASE 24
|
|
|
|
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4, .lcap_port_base = 1 },
|
|
{ 0 }
|
|
};
|
|
|
|
static const struct pcie_rp_group pch_m_rp_groups[] = {
|
|
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8, .lcap_port_base = 1 },
|
|
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 2, .lcap_port_base = 1 },
|
|
{ 0 }
|
|
};
|
|
|
|
const struct pcie_rp_group *get_pch_pcie_rp_table(void)
|
|
{
|
|
if (CONFIG(SOC_INTEL_ALDERLAKE_PCH_M))
|
|
return pch_m_rp_groups;
|
|
|
|
return pch_lp_rp_groups; /* Valid for PCH-P and PCH-N */
|
|
}
|
|
|
|
/*
|
|
* ADL-P FSP define CPU RP as below:
|
|
* RP1: PEG60 : 0:6:0 : x4 CPU Slot
|
|
* RP2: PEG10 : 0:1:0 : x8 CPU Slot
|
|
* RP3: PEG62 : 0:6:2 : x4 CPU Slot
|
|
*/
|
|
static const struct pcie_rp_group cpu_rp_groups[] = {
|
|
{ .slot = SA_DEV_SLOT_CPU_6, .start = 0, .count = 1, .lcap_port_base = 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, .lcap_port_base = 1 },
|
|
{ 0 }
|
|
};
|
|
|
|
static const struct pcie_rp_group cpu_m_rp_groups[] = {
|
|
{ .slot = SA_DEV_SLOT_CPU_6, .start = 0, .count = 1, .lcap_port_base = 1 },
|
|
{ 0 }
|
|
};
|
|
|
|
static const struct pcie_rp_group cpu_n_rp_groups[] = {
|
|
{ 0 }
|
|
};
|
|
|
|
const struct pcie_rp_group *get_cpu_pcie_rp_table(void)
|
|
{
|
|
if (CONFIG(SOC_INTEL_ALDERLAKE_PCH_M))
|
|
return cpu_m_rp_groups;
|
|
|
|
if (CONFIG(SOC_INTEL_ALDERLAKE_PCH_N))
|
|
return cpu_n_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[] = {
|
|
{ .slot = SA_DEV_SLOT_TBT, .count = CONFIG_MAX_TBT_ROOT_PORTS, .lcap_port_base = 2 },
|
|
{ 0 }
|
|
};
|
|
|
|
const struct pcie_rp_group *get_tbt_pcie_rp_table(void)
|
|
{
|
|
return tbt_rp_groups;
|
|
}
|
|
|
|
static bool is_part_of_group(const struct device *dev,
|
|
const struct pcie_rp_group *groups)
|
|
{
|
|
if (dev->path.type != DEVICE_PATH_PCI)
|
|
return false;
|
|
|
|
const unsigned int slot_to_find = PCI_SLOT(dev->path.pci.devfn);
|
|
const unsigned int fn_to_find = PCI_FUNC(dev->path.pci.devfn);
|
|
const struct pcie_rp_group *group;
|
|
unsigned int i;
|
|
unsigned int fn;
|
|
|
|
for (group = groups; group->count; ++group) {
|
|
for (i = 0, fn = rp_start_fn(group); i < group->count; i++, fn++) {
|
|
if (slot_to_find == group->slot && fn_to_find == fn)
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
enum pcie_rp_type soc_get_pcie_rp_type(const struct device *dev)
|
|
{
|
|
if (is_part_of_group(dev, pch_lp_rp_groups))
|
|
return PCIE_RP_PCH;
|
|
|
|
if (CONFIG_MAX_CPU_ROOT_PORTS && is_part_of_group(dev, cpu_rp_groups))
|
|
return PCIE_RP_CPU;
|
|
|
|
return PCIE_RP_UNKNOWN;
|
|
}
|
|
|
|
int soc_get_cpu_rp_vw_idx(const struct device *dev)
|
|
{
|
|
if (dev->path.type != DEVICE_PATH_PCI)
|
|
return -1;
|
|
|
|
switch (dev->path.pci.devfn) {
|
|
case SA_DEVFN_CPU_PCIE1_0:
|
|
return CPU_CPIE_VW_IDX_BASE;
|
|
case SA_DEVFN_CPU_PCIE6_0:
|
|
return CPU_CPIE_VW_IDX_BASE + 3;
|
|
case SA_DEVFN_CPU_PCIE6_2:
|
|
return CPU_CPIE_VW_IDX_BASE + 2;
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|