Files
system76-coreboot/src/soc/intel/alderlake/pcie_rp.c
MAULIK V VAGHELA d9c5b14f1e 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>
2022-02-25 18:59:51 +00:00

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;
}
}