Add bd82x6x mainboards ASPM overrides.
The Intel PCH can override the ASPM settings via the MPC2 register. Add a chip override for F0-F7. Mainboards may implement this as needed. This also fixes the final PM setup being done too early. It was being done prior to the PCIe ASPM setup, which happens in the bridge scan. Change-Id: Idf2d2374899873fc6b1a2b00abdb683ea9f5bd6b Signed-off-by: Marc Jones <marc.jones@se-eng.com> Reviewed-on: http://review.coreboot.org/1796 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
2a700ec163
commit
4adc8cdd18
|
@ -77,6 +77,16 @@ struct southbridge_intel_bd82x6x_config {
|
||||||
|
|
||||||
/* Enable linear PCIe Root Port function numbers starting at zero */
|
/* Enable linear PCIe Root Port function numbers starting at zero */
|
||||||
uint8_t pcie_port_coalesce;
|
uint8_t pcie_port_coalesce;
|
||||||
|
|
||||||
|
/* Override PCIe ASPM */
|
||||||
|
uint8_t pcie_aspm_f0;
|
||||||
|
uint8_t pcie_aspm_f1;
|
||||||
|
uint8_t pcie_aspm_f2;
|
||||||
|
uint8_t pcie_aspm_f3;
|
||||||
|
uint8_t pcie_aspm_f4;
|
||||||
|
uint8_t pcie_aspm_f5;
|
||||||
|
uint8_t pcie_aspm_f6;
|
||||||
|
uint8_t pcie_aspm_f7;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SOUTHBRIDGE_INTEL_BD82X6X_CHIP_H */
|
#endif /* SOUTHBRIDGE_INTEL_BD82X6X_CHIP_H */
|
||||||
|
|
|
@ -134,7 +134,8 @@ static void pch_pcie_pm_early(struct device *dev)
|
||||||
|
|
||||||
static void pch_pcie_pm_late(struct device *dev)
|
static void pch_pcie_pm_late(struct device *dev)
|
||||||
{
|
{
|
||||||
enum aspm_type apmc;
|
struct southbridge_intel_bd82x6x_config *config = dev->chip_info;
|
||||||
|
enum aspm_type apmc = 0;
|
||||||
u32 reg32;
|
u32 reg32;
|
||||||
|
|
||||||
/* Set 0x314 = 0x743a361b */
|
/* Set 0x314 = 0x743a361b */
|
||||||
|
@ -168,8 +169,42 @@ static void pch_pcie_pm_late(struct device *dev)
|
||||||
reg32 |= (1 << 1);
|
reg32 |= (1 << 1);
|
||||||
pci_write_config32(dev, 0xd4, reg32);
|
pci_write_config32(dev, 0xd4, reg32);
|
||||||
|
|
||||||
/* Get configured ASPM state */
|
/* Check for a rootport ASPM override */
|
||||||
|
switch (PCI_FUNC(dev->path.pci.devfn)) {
|
||||||
|
case 0:
|
||||||
|
apmc = config->pcie_aspm_f0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
apmc = config->pcie_aspm_f1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
apmc = config->pcie_aspm_f2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
apmc = config->pcie_aspm_f3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
apmc = config->pcie_aspm_f4;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
apmc = config->pcie_aspm_f5;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
apmc = config->pcie_aspm_f6;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
apmc = config->pcie_aspm_f7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the override or get the real ASPM setting */
|
||||||
|
if (apmc) {
|
||||||
|
reg32 = pci_read_config32(dev, 0xd4);
|
||||||
|
reg32 |= (apmc << 2) | (1 << 4);
|
||||||
|
pci_write_config32(dev, 0xd4, reg32);
|
||||||
|
} else {
|
||||||
apmc = pci_read_config32(dev, 0x50) & 3;
|
apmc = pci_read_config32(dev, 0x50) & 3;
|
||||||
|
}
|
||||||
|
|
||||||
/* If both L0s and L1 enabled then set root port 0xE8[1]=1 */
|
/* If both L0s and L1 enabled then set root port 0xE8[1]=1 */
|
||||||
if (apmc == PCIE_ASPM_BOTH) {
|
if (apmc == PCIE_ASPM_BOTH) {
|
||||||
|
@ -220,9 +255,6 @@ static void pci_init(struct device *dev)
|
||||||
reg16 = pci_read_config16(dev, 0x1e);
|
reg16 = pci_read_config16(dev, 0x1e);
|
||||||
//reg16 |= 0xf900;
|
//reg16 |= 0xf900;
|
||||||
pci_write_config16(dev, 0x1e, reg16);
|
pci_write_config16(dev, 0x1e, reg16);
|
||||||
|
|
||||||
/* Power Management init after enumeration */
|
|
||||||
pch_pcie_pm_late(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pch_pcie_enable(device_t dev)
|
static void pch_pcie_enable(device_t dev)
|
||||||
|
@ -231,6 +263,19 @@ static void pch_pcie_enable(device_t dev)
|
||||||
pch_pcie_pm_early(dev);
|
pch_pcie_pm_early(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int pch_pciexp_scan_bridge(device_t dev, unsigned int max)
|
||||||
|
{
|
||||||
|
unsigned int ret;
|
||||||
|
|
||||||
|
/* Normal PCIe Scan */
|
||||||
|
ret = pciexp_scan_bridge(dev, max);
|
||||||
|
|
||||||
|
/* Late Power Management init after bridge device enumeration */
|
||||||
|
pch_pcie_pm_late(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
||||||
{
|
{
|
||||||
/* NOTE: This is not the default position! */
|
/* NOTE: This is not the default position! */
|
||||||
|
@ -253,7 +298,7 @@ static struct device_operations device_ops = {
|
||||||
.enable_resources = pci_bus_enable_resources,
|
.enable_resources = pci_bus_enable_resources,
|
||||||
.init = pci_init,
|
.init = pci_init,
|
||||||
.enable = pch_pcie_enable,
|
.enable = pch_pcie_enable,
|
||||||
.scan_bus = pciexp_scan_bridge,
|
.scan_bus = pch_pciexp_scan_bridge,
|
||||||
.ops_pci = &pci_ops,
|
.ops_pci = &pci_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue