aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/sandybridge/early_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/intel/sandybridge/early_init.c')
-rw-r--r--src/northbridge/intel/sandybridge/early_init.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/northbridge/intel/sandybridge/early_init.c b/src/northbridge/intel/sandybridge/early_init.c
index 81bf9d5854..b8daedc133 100644
--- a/src/northbridge/intel/sandybridge/early_init.c
+++ b/src/northbridge/intel/sandybridge/early_init.c
@@ -148,6 +148,41 @@ static void sandybridge_setup_graphics(void)
MCHBAR32(0x5418) = reg32;
}
+static void start_peg_link_training(void)
+{
+ u32 tmp;
+ u32 deven;
+
+ /* PEG on IvyBridge+ needs a special startup sequence.
+ * As the MRC has its own initialization code skip it. */
+ if (((pci_read_config16(PCI_DEV(0, 0, 0), PCI_DEVICE_ID) &
+ BASE_REV_MASK) != BASE_REV_IVB) ||
+ IS_ENABLED(CONFIG_HAVE_MRC))
+ return;
+
+ deven = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
+
+ if (deven & DEVEN_PEG10) {
+ tmp = pci_read_config32(PCI_DEV(0, 1, 0), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 1, 0), 0xC24, tmp | (1 << 5));
+ }
+
+ if (deven & DEVEN_PEG11) {
+ tmp = pci_read_config32(PCI_DEV(0, 1, 1), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 1, 1), 0xC24, tmp | (1 << 5));
+ }
+
+ if (deven & DEVEN_PEG12) {
+ tmp = pci_read_config32(PCI_DEV(0, 1, 2), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 1, 2), 0xC24, tmp | (1 << 5));
+ }
+
+ if (deven & DEVEN_PEG60) {
+ tmp = pci_read_config32(PCI_DEV(0, 6, 0), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 6, 0), 0xC24, tmp | (1 << 5));
+ }
+}
+
void sandybridge_early_initialization(int chipset_type)
{
u32 capid0_a;
@@ -177,6 +212,15 @@ void sandybridge_early_initialization(int chipset_type)
pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, deven);
sandybridge_setup_graphics();
+
+ /* Write magic value to start PEG link training.
+ * This should be done in PCI device enumeration, but
+ * the PCIe specification requires to wait at least 100msec
+ * after reset for devices to come up.
+ * As we don't want to increase boot time, enable it early and
+ * assume the PEG is up as soon as PCI enumeration starts.
+ * TODO: use time stamps to ensure the timings are met */
+ start_peg_link_training();
}
void northbridge_romstage_finalize(int s3resume)