sb/intel/bd82x6x: make hotplug map consistent to remapped ports

"pcie_port_coalesce" will cause pcie being remapped under certain
conditions, but flags within "pcie_hotplug_map" should be updated
along with ports.

Test on my lenovo t430s.

Change-Id: I28c4eaf82fb52fe793dfa2f824f14686b80951ad
Signed-off-by: Bill XIE <persmule@gmail.com>
Reviewed-on: https://review.coreboot.org/21178
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Bill XIE 2017-08-25 22:07:12 +08:00 committed by Nico Huber
parent eeab2710ef
commit 8c57d09729
1 changed files with 32 additions and 3 deletions

View File

@ -25,7 +25,7 @@
#include <device/pci.h> #include <device/pci.h>
#endif #endif
#include "pch.h" #include "pch.h"
#include <string.h>
int pch_silicon_revision(void) int pch_silicon_revision(void)
{ {
@ -255,10 +255,24 @@ static void pch_pcie_function_swap(u8 old_fn, u8 new_fn)
} }
/* Update devicetree with new Root Port function number assignment */ /* Update devicetree with new Root Port function number assignment */
static void pch_pcie_devicetree_update(void) static void pch_pcie_devicetree_update(
struct southbridge_intel_bd82x6x_config *config)
{ {
device_t dev; device_t dev;
/*
* hotplug map should also be updated along with their
* corresponding port
*/
u8 new_hotplug_map[sizeof(config->pcie_hotplug_map)];
/*
* Slots that didn't move need the hotplug setting copied too,
* so "new_hotplug_map" is initialized with the values of the old map.
*/
memcpy(new_hotplug_map, config->pcie_hotplug_map,
sizeof(new_hotplug_map));
/* Update the function numbers in the static devicetree */ /* Update the function numbers in the static devicetree */
for (dev = all_devices; dev; dev = dev->next) { for (dev = all_devices; dev; dev = dev->next) {
u8 new_devfn; u8 new_devfn;
@ -280,9 +294,21 @@ static void pch_pcie_devicetree_update(void)
PCI_FUNC(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn),
PCI_SLOT(new_devfn), PCI_FUNC(new_devfn)); PCI_SLOT(new_devfn), PCI_FUNC(new_devfn));
/*
* Copy the flag to its new position along with
* the corresponding port
*/
new_hotplug_map[PCI_FUNC(new_devfn)] =
config->pcie_hotplug_map
[PCI_FUNC(dev->path.pci.devfn)];
dev->path.pci.devfn = new_devfn; dev->path.pci.devfn = new_devfn;
} }
} }
/* Copy the updated map back to its place */
memcpy(config->pcie_hotplug_map, new_hotplug_map,
sizeof(new_hotplug_map));
} }
/* Special handling for PCIe Root Port devices */ /* Special handling for PCIe Root Port devices */
@ -291,6 +317,9 @@ static void pch_pcie_enable(device_t dev)
struct southbridge_intel_bd82x6x_config *config = dev->chip_info; struct southbridge_intel_bd82x6x_config *config = dev->chip_info;
u32 reg32; u32 reg32;
if (!config)
return;
/* /*
* Save a copy of the Root Port Function Number map when * Save a copy of the Root Port Function Number map when
* starting to walk the list of PCIe Root Ports so it can * starting to walk the list of PCIe Root Ports so it can
@ -389,7 +418,7 @@ static void pch_pcie_enable(device_t dev)
/* Update static devictree with new function numbers */ /* Update static devictree with new function numbers */
if (config->pcie_port_coalesce) if (config->pcie_port_coalesce)
pch_pcie_devicetree_update(); pch_pcie_devicetree_update(config);
} }
} }