nb/intel/sandybridge: Add a bunch of MCHBAR defines

While we are at it, also:
- Rename related variables to match the register names.
- Update some comments to better reflect what some registers are about.
- Add various FIXME comments on registers that seem to be used wrongly.

With BUILD_TIMELESS=1, this commit does not change the coreboot build of:
- Asus P8H61-M PRO with native raminit.
- Gigabyte GA-H61MA-D3V with native raminit.
- Lenovo Thinkpad X230 with native raminit.
- Lenovo Thinkpad X220 with MRC raminit.

Change-Id: I5e5fe56eaa90842dbbdd1bfbbcb7709237b4c486
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38036
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
Angel Pons
2020-01-05 20:21:20 +01:00
committed by Felix Held
parent d589be3648
commit 8852188113
10 changed files with 1065 additions and 732 deletions

View File

@ -34,10 +34,10 @@ static void systemagent_vtd_init(void)
return;
/* setup BARs */
MCHBAR32(0x5404) = IOMMU_BASE1 >> 32;
MCHBAR32(0x5400) = IOMMU_BASE1 | 1;
MCHBAR32(0x5414) = IOMMU_BASE2 >> 32;
MCHBAR32(0x5410) = IOMMU_BASE2 | 1;
MCHBAR32(VTD1_BASE + 4) = IOMMU_BASE1 >> 32;
MCHBAR32(VTD1_BASE) = IOMMU_BASE1 | 1;
MCHBAR32(VTD2_BASE + 4) = IOMMU_BASE2 >> 32;
MCHBAR32(VTD2_BASE) = IOMMU_BASE2 | 1;
/* lock policies */
write32((void *)(IOMMU_BASE1 + 0xff0), 0x80000000);
@ -126,13 +126,13 @@ static void sandybridge_setup_graphics(void)
pci_write_config8(PCI_DEV(0, 2, 0), MSAC, reg8);
/* Erratum workarounds */
reg32 = MCHBAR32(0x5f00);
reg32 = MCHBAR32(SAPMCTL);
reg32 |= (1 << 9)|(1 << 10);
MCHBAR32(0x5f00) = reg32;
MCHBAR32(SAPMCTL) = reg32;
/* Enable SA Clock Gating */
reg32 = MCHBAR32(0x5f00);
MCHBAR32(0x5f00) = reg32 | 1;
reg32 = MCHBAR32(SAPMCTL);
MCHBAR32(SAPMCTL) = reg32 | 1;
/* GPU RC6 workaround for sighting 366252 */
reg32 = MCHBAR32(0x5d14);
@ -144,9 +144,9 @@ static void sandybridge_setup_graphics(void)
reg32 &= ~(1 << 0);
MCHBAR32(0x6120) = reg32;
reg32 = MCHBAR32(0x5418);
reg32 = MCHBAR32(PAIR_CTL);
reg32 |= (1 << 4) | (1 << 5);
MCHBAR32(0x5418) = reg32;
MCHBAR32(PAIR_CTL) = reg32;
}
static void start_peg_link_training(void)

View File

@ -34,8 +34,8 @@ void intel_sandybridge_finalize_smm(void)
pci_or_config32(PCI_DEV_SNB, TSEGMB, 1 << 0);
pci_or_config32(PCI_DEV_SNB, TOLUD, 1 << 0);
MCHBAR32_OR(0x5500, 1 << 0); /* PAVP */
MCHBAR32_OR(0x5f00, 1 << 31); /* SA PM */
MCHBAR32_OR(MMIO_PAVP_CTL, 1 << 0); /* PAVP */
MCHBAR32_OR(SAPMCTL, 1 << 31); /* SA PM */
MCHBAR32_OR(0x6020, 1 << 0); /* UMA GFX */
MCHBAR32_OR(0x63fc, 1 << 0); /* VTDTRK */
MCHBAR32_OR(0x6800, 1 << 31);
@ -43,7 +43,7 @@ void intel_sandybridge_finalize_smm(void)
MCHBAR32_OR(0x77fc, 1 << 0);
/* Memory Controller Lockdown */
MCHBAR8(0x50fc) = 0x8f;
MCHBAR8(MC_LOCK) = 0x8f;
/* Read+write the following */
MCHBAR32(0x6030) = MCHBAR32(0x6030);

View File

@ -391,15 +391,15 @@ static void northbridge_init(struct device *dev)
northbridge_dmi_init(dev);
bridge_type = MCHBAR32(0x5f10);
bridge_type = MCHBAR32(SAPMTIMERS);
bridge_type &= ~0xff;
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
/* Enable Power Aware Interrupt Routing */
u8 pair = MCHBAR8(0x5418);
u8 pair = MCHBAR8(PAIR_CTL);
pair &= ~0xf; /* Clear 3:0 */
pair |= 0x4; /* Fixed Priority */
MCHBAR8(0x5418) = pair;
MCHBAR8(PAIR_CTL) = pair;
/* 30h for IvyBridge */
bridge_type |= 0x30;
@ -407,7 +407,7 @@ static void northbridge_init(struct device *dev)
/* 20h for Sandybridge */
bridge_type |= 0x20;
}
MCHBAR32(0x5f10) = bridge_type;
MCHBAR32(SAPMTIMERS) = bridge_type;
/* Turn off unused devices. Has to be done before
* setting BIOS_RESET_CPL.
@ -433,12 +433,12 @@ static void northbridge_init(struct device *dev)
*/
if (cpu_config_tdp_levels()) {
msr_t msr = rdmsr(MSR_PKG_POWER_LIMIT);
MCHBAR32(0x59A0) = msr.lo;
MCHBAR32(0x59A4) = msr.hi;
MCHBAR32(MC_TURBO_PL1) = msr.lo;
MCHBAR32(MC_TURBO_PL2) = msr.hi;
}
/* Set here before graphics PM init */
MCHBAR32(0x5500) = 0x00100001;
MCHBAR32(MMIO_PAVP_CTL) = 0x00100001;
}
void northbridge_write_smram(u8 smram)

View File

@ -293,7 +293,7 @@ static void init_dram_ddr3(int min_tck, int s3resume)
int err;
u32 cpu;
MCHBAR32(0x5f00) |= 1;
MCHBAR32(SAPMCTL) |= 1;
/* Wait for ME to be ready */
intel_early_me_init();
@ -404,12 +404,12 @@ static void init_dram_ddr3(int min_tck, int s3resume)
if (err)
die("raminit failed");
/* FIXME: should be hardware revision-dependent. */
MCHBAR32(0x5024) = 0x00a030ce;
/* FIXME: should be hardware revision-dependent. The register only exists on IVB. */
MCHBAR32(CHANNEL_HASH) = 0x00a030ce;
set_scrambling_seed(&ctrl);
set_42a0(&ctrl);
set_normal_operation(&ctrl);
final_registers(&ctrl);

File diff suppressed because it is too large Load Diff

View File

@ -52,12 +52,14 @@ typedef struct dimm_info_st {
} dimm_info;
struct ram_rank_timings {
/* Register 4024. One byte per slotrank. */
u8 val_4024;
/* ROUNDT_LAT register. One byte per slotrank. */
u8 roundtrip_latency;
/* IO_LATENCY register. One nibble per slotrank. */
u8 io_latency;
int val_320c;
/* Phase interpolator coding for command and control. */
int pi_coding;
struct ram_lane_timings {
/* lane register offset 0x10. */
@ -109,7 +111,8 @@ typedef struct ramctr_timing_st {
u32 tXP;
u32 tAONPD;
u16 reg_5064b0; /* bits 0-11. */
/* Bits [0..11] of PM_DLL_CONFIG: Master DLL wakeup delay timer. */
u16 mdll_wake_delay;
u8 rankmap[NUM_CHANNELS];
int ref_card_offset[NUM_CHANNELS];
@ -117,8 +120,8 @@ typedef struct ramctr_timing_st {
int channel_size_mb[NUM_CHANNELS];
u32 cmd_stretch[NUM_CHANNELS];
int reg_c14_offset;
int reg_320c_range_threshold;
int pi_code_offset;
int pi_coding_threshold;
int edge_offset[3];
int timC_offset[3];
@ -174,7 +177,7 @@ void set_scrambling_seed(ramctr_timing * ctrl);
void set_4f8c(void);
void prepare_training(ramctr_timing *ctrl);
void set_4008c(ramctr_timing *ctrl);
void set_42a0(ramctr_timing * ctrl);
void set_normal_operation(ramctr_timing *ctrl);
void final_registers(ramctr_timing *ctrl);
void restore_timings(ramctr_timing *ctrl);

View File

@ -388,7 +388,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 20; //XXX: guessed
ctrl->timC_offset[1] = 8;
ctrl->timC_offset[2] = 8;
ctrl->reg_320c_range_threshold = 10;
ctrl->pi_coding_threshold = 10;
} else if (ctrl->tCK == TCK_1100MHZ) {
ctrl->edge_offset[0] = 17; //XXX: guessed
ctrl->edge_offset[1] = 7;
@ -396,7 +396,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 19; //XXX: guessed
ctrl->timC_offset[1] = 7;
ctrl->timC_offset[2] = 7;
ctrl->reg_320c_range_threshold = 13;
ctrl->pi_coding_threshold = 13;
} else if (ctrl->tCK == TCK_1066MHZ) {
ctrl->edge_offset[0] = 16;
ctrl->edge_offset[1] = 7;
@ -404,7 +404,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 18;
ctrl->timC_offset[1] = 7;
ctrl->timC_offset[2] = 7;
ctrl->reg_320c_range_threshold = 13;
ctrl->pi_coding_threshold = 13;
} else if (ctrl->tCK == TCK_1000MHZ) {
ctrl->edge_offset[0] = 15; //XXX: guessed
ctrl->edge_offset[1] = 6;
@ -412,7 +412,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 17; //XXX: guessed
ctrl->timC_offset[1] = 6;
ctrl->timC_offset[2] = 6;
ctrl->reg_320c_range_threshold = 13;
ctrl->pi_coding_threshold = 13;
} else if (ctrl->tCK == TCK_933MHZ) {
ctrl->edge_offset[0] = 14;
ctrl->edge_offset[1] = 6;
@ -420,7 +420,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 15;
ctrl->timC_offset[1] = 6;
ctrl->timC_offset[2] = 6;
ctrl->reg_320c_range_threshold = 15;
ctrl->pi_coding_threshold = 15;
} else if (ctrl->tCK == TCK_900MHZ) {
ctrl->edge_offset[0] = 14; //XXX: guessed
ctrl->edge_offset[1] = 6;
@ -428,7 +428,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 15; //XXX: guessed
ctrl->timC_offset[1] = 6;
ctrl->timC_offset[2] = 6;
ctrl->reg_320c_range_threshold = 12;
ctrl->pi_coding_threshold = 12;
} else if (ctrl->tCK == TCK_800MHZ) {
ctrl->edge_offset[0] = 13;
ctrl->edge_offset[1] = 5;
@ -436,7 +436,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 14;
ctrl->timC_offset[1] = 5;
ctrl->timC_offset[2] = 5;
ctrl->reg_320c_range_threshold = 15;
ctrl->pi_coding_threshold = 15;
} else if (ctrl->tCK == TCK_700MHZ) {
ctrl->edge_offset[0] = 13; //XXX: guessed
ctrl->edge_offset[1] = 5;
@ -444,7 +444,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 14; //XXX: guessed
ctrl->timC_offset[1] = 5;
ctrl->timC_offset[2] = 5;
ctrl->reg_320c_range_threshold = 16;
ctrl->pi_coding_threshold = 16;
} else if (ctrl->tCK == TCK_666MHZ) {
ctrl->edge_offset[0] = 10;
ctrl->edge_offset[1] = 4;
@ -452,7 +452,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 11;
ctrl->timC_offset[1] = 4;
ctrl->timC_offset[2] = 4;
ctrl->reg_320c_range_threshold = 16;
ctrl->pi_coding_threshold = 16;
} else if (ctrl->tCK == TCK_533MHZ) {
ctrl->edge_offset[0] = 8;
ctrl->edge_offset[1] = 3;
@ -460,7 +460,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 9;
ctrl->timC_offset[1] = 3;
ctrl->timC_offset[2] = 3;
ctrl->reg_320c_range_threshold = 17;
ctrl->pi_coding_threshold = 17;
} else { /* TCK_400MHZ */
ctrl->edge_offset[0] = 6;
ctrl->edge_offset[1] = 2;
@ -468,14 +468,14 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 6;
ctrl->timC_offset[1] = 2;
ctrl->timC_offset[2] = 2;
ctrl->reg_320c_range_threshold = 17;
ctrl->pi_coding_threshold = 17;
}
/* Initial phase between CLK/CMD pins */
ctrl->reg_c14_offset = (256000 / ctrl->tCK) / 66;
ctrl->pi_code_offset = (256000 / ctrl->tCK) / 66;
/* DLL_CONFIG_MDLL_W_TIMER */
ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
ctrl->mdll_wake_delay = (128000 / ctrl->tCK) + 3;
if (ctrl->tCWL)
ctrl->CWL = DIV_ROUND_UP(ctrl->tCWL, ctrl->tCK);
@ -590,12 +590,12 @@ static void dram_ioregs(ramctr_timing * ctrl)
// IO clock
FOR_ALL_CHANNELS {
MCHBAR32(0xc00 + channel * 0x100) = ctrl->rankmap[channel];
MCHBAR32(GDCRCLKRANKSUSED_ch(channel)) = ctrl->rankmap[channel];
}
// IO command
FOR_ALL_CHANNELS {
MCHBAR32(0x3200 + channel * 0x100) = ctrl->rankmap[channel];
MCHBAR32(GDCRCTLRANKSUSED_ch(channel)) = ctrl->rankmap[channel];
}
// IO control
@ -607,27 +607,27 @@ static void dram_ioregs(ramctr_timing * ctrl)
printram("RCOMP...");
reg = 0;
while (reg == 0) {
reg = MCHBAR32(0x5084) & 0x10000;
reg = MCHBAR32(RCOMP_TIMER) & 0x10000;
}
printram("done\n");
// Set comp2
comp2 = get_COMP2(ctrl->tCK, ctrl->base_freq);
MCHBAR32(0x3714) = comp2;
MCHBAR32(CRCOMPOFST2) = comp2;
printram("COMP2 done\n");
// Set comp1
FOR_ALL_POPULATED_CHANNELS {
reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
reg = MCHBAR32(CRCOMPOFST1_ch(channel)); //ch0
reg = (reg & ~0xe00) | (1 << 9); //odt
reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
MCHBAR32(0x1810 + channel * 0x100) = reg;
MCHBAR32(CRCOMPOFST1_ch(channel)) = reg;
}
printram("COMP1 done\n");
printram("FORCE RCOMP and wait 20us...");
MCHBAR32(0x5f08) |= 0x100;
MCHBAR32(M_COMP) |= 0x100;
udelay(20);
printram("done\n");
}
@ -656,7 +656,7 @@ int try_init_dram_ddr3_ivy(ramctr_timing *ctrl, int fast_boot,
}
/* Set version register */
MCHBAR32(0x5034) = 0xC04EB002;
MCHBAR32(MRC_REVISION) = 0xC04EB002;
/* Enable crossover */
dram_xover(ctrl);
@ -665,16 +665,16 @@ int try_init_dram_ddr3_ivy(ramctr_timing *ctrl, int fast_boot,
dram_timing_regs(ctrl);
/* Power mode preset */
MCHBAR32(0x4e80) = 0x5500;
MCHBAR32(PM_THML_STAT) = 0x5500;
/* Set scheduler parameters */
MCHBAR32(0x4c20) = 0x10100005;
/* Set scheduler chicken bits */
MCHBAR32(SCHED_CBIT) = 0x10100005;
/* Set CPU specific register */
set_4f8c();
/* Clear IO reset bit */
MCHBAR32(0x5030) &= ~0x20;
MCHBAR32(MC_INIT_STATE_G) &= ~0x20;
/* Set MAD-DIMM registers */
dram_dimm_set_mapping(ctrl);

View File

@ -249,7 +249,7 @@ void sdram_initialize(struct pei_data *pei_data)
/* For reference print the System Agent version
* after executing the UEFI PEI stage.
*/
u32 version = MCHBAR32(0x5034);
u32 version = MCHBAR32(MRC_REVISION);
printk(BIOS_DEBUG, "System Agent Version %d.%d.%d Build %d\n",
version >> 24, (version >> 16) & 0xff,
(version >> 8) & 0xff, version & 0xff);

View File

@ -200,7 +200,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 18;
ctrl->timC_offset[1] = 7;
ctrl->timC_offset[2] = 7;
ctrl->reg_320c_range_threshold = 13;
ctrl->pi_coding_threshold = 13;
} else if (ctrl->tCK == TCK_933MHZ) {
ctrl->edge_offset[0] = 14;
ctrl->edge_offset[1] = 6;
@ -208,7 +208,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 15;
ctrl->timC_offset[1] = 6;
ctrl->timC_offset[2] = 6;
ctrl->reg_320c_range_threshold = 15;
ctrl->pi_coding_threshold = 15;
} else if (ctrl->tCK == TCK_800MHZ) {
ctrl->edge_offset[0] = 13;
ctrl->edge_offset[1] = 5;
@ -216,7 +216,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 14;
ctrl->timC_offset[1] = 5;
ctrl->timC_offset[2] = 5;
ctrl->reg_320c_range_threshold = 15;
ctrl->pi_coding_threshold = 15;
} else if (ctrl->tCK == TCK_666MHZ) {
ctrl->edge_offset[0] = 10;
ctrl->edge_offset[1] = 4;
@ -224,7 +224,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 11;
ctrl->timC_offset[1] = 4;
ctrl->timC_offset[2] = 4;
ctrl->reg_320c_range_threshold = 16;
ctrl->pi_coding_threshold = 16;
} else if (ctrl->tCK == TCK_533MHZ) {
ctrl->edge_offset[0] = 8;
ctrl->edge_offset[1] = 3;
@ -232,7 +232,7 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 9;
ctrl->timC_offset[1] = 3;
ctrl->timC_offset[2] = 3;
ctrl->reg_320c_range_threshold = 17;
ctrl->pi_coding_threshold = 17;
} else {
ctrl->tCK = TCK_400MHZ;
ctrl->edge_offset[0] = 6;
@ -241,14 +241,14 @@ static void dram_timing(ramctr_timing *ctrl)
ctrl->timC_offset[0] = 6;
ctrl->timC_offset[1] = 2;
ctrl->timC_offset[2] = 2;
ctrl->reg_320c_range_threshold = 17;
ctrl->pi_coding_threshold = 17;
}
/* Initial phase between CLK/CMD pins */
ctrl->reg_c14_offset = (256000 / ctrl->tCK) / 66;
ctrl->pi_code_offset = (256000 / ctrl->tCK) / 66;
/* DLL_CONFIG_MDLL_W_TIMER */
ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
ctrl->mdll_wake_delay = (128000 / ctrl->tCK) + 3;
if (ctrl->tCWL)
ctrl->CWL = DIV_ROUND_UP(ctrl->tCWL, ctrl->tCK);
@ -361,12 +361,12 @@ static void dram_ioregs(ramctr_timing * ctrl)
// IO clock
FOR_ALL_CHANNELS {
MCHBAR32(0xc00 + channel * 0x100) = ctrl->rankmap[channel];
MCHBAR32(GDCRCLKRANKSUSED_ch(channel)) = ctrl->rankmap[channel];
}
// IO command
FOR_ALL_CHANNELS {
MCHBAR32(0x3200 + channel * 0x100) = ctrl->rankmap[channel];
MCHBAR32(GDCRCTLRANKSUSED_ch(channel)) = ctrl->rankmap[channel];
}
// IO control
@ -378,27 +378,27 @@ static void dram_ioregs(ramctr_timing * ctrl)
printram("RCOMP...");
reg = 0;
while (reg == 0) {
reg = MCHBAR32(0x5084) & 0x10000;
reg = MCHBAR32(RCOMP_TIMER) & 0x10000;
}
printram("done\n");
// Set comp2
comp2 = get_COMP2(ctrl->tCK);
MCHBAR32(0x3714) = comp2;
MCHBAR32(CRCOMPOFST2) = comp2;
printram("COMP2 done\n");
// Set comp1
FOR_ALL_POPULATED_CHANNELS {
reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
reg = MCHBAR32(CRCOMPOFST1_ch(channel)); //ch0
reg = (reg & ~0xe00) | (1 << 9); //odt
reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
MCHBAR32(0x1810 + channel * 0x100) = reg;
MCHBAR32(CRCOMPOFST1_ch(channel)) = reg;
}
printram("COMP1 done\n");
printram("FORCE RCOMP and wait 20us...");
MCHBAR32(0x5f08) |= 0x100;
MCHBAR32(M_COMP) |= 0x100;
udelay(20);
printram("done\n");
}
@ -427,7 +427,7 @@ int try_init_dram_ddr3_sandy(ramctr_timing *ctrl, int fast_boot,
}
/* Set version register */
MCHBAR32(0x5034) = 0xC04EB002;
MCHBAR32(MRC_REVISION) = 0xC04EB002;
/* Enable crossover */
dram_xover(ctrl);
@ -436,16 +436,16 @@ int try_init_dram_ddr3_sandy(ramctr_timing *ctrl, int fast_boot,
dram_timing_regs(ctrl);
/* Power mode preset */
MCHBAR32(0x4e80) = 0x5500;
MCHBAR32(PM_THML_STAT) = 0x5500;
/* Set scheduler parameters */
MCHBAR32(0x4c20) = 0x10100005;
/* Set scheduler chicken bits */
MCHBAR32(SCHED_CBIT) = 0x10100005;
/* Set CPU specific register */
set_4f8c();
/* Clear IO reset bit */
MCHBAR32(0x5030) &= ~0x20;
MCHBAR32(MC_INIT_STATE_G) &= ~0x20;
/* Set MAD-DIMM registers */
dram_dimm_set_mapping(ctrl);

View File

@ -127,23 +127,218 @@ enum platform_type {
#define MCHBAR32_AND(x, and) (MCHBAR32(x) = (MCHBAR32(x) & (and)))
#define MCHBAR32_AND_OR(x, and, or) (MCHBAR32(x) = (MCHBAR32(x) & (and)) | (or))
#define TC_DBP_C0 0x4000 /* Timing of DDR - bin parameters */
#define TC_RAP_C0 0x4004 /* Timing of DDR - regular access parameters */
#define SC_IO_LATENCY_C0 0x4028 /* IO Latency Configuration */
#define TC_RFP_C0 0x4294 /* Refresh Parameters */
#define TC_RFTP_C0 0x4298 /* Refresh Timing Parameters */
#define PM_PDWN_CONFIG 0x4cb0
/* Indexed register helper macros */
#define Gz(r, z) ((r) + ((z) * 0x100))
#define Ly(r, y) ((r) + ((y) * 4))
#define Cx(r, x) ((r) + ((x) * 0x400))
/* FIXME: These two are equivalent, but had to be split for reproducibility reasons. */
#define CxLy(r, x, y) ((r) + ((x) * 0x400) + ((y) * 4))
#define LyCx(r, x, y) ((r) + ((y) * 4) + ((x) * 0x400))
/* Register definitions */
#define GDCRCLKRANKSUSED_ch(ch) Gz(0x0c00, ch) /* Indicates which rank is populated */
#define GDCRCLKCOMP_ch(ch) Gz(0x0c04, ch) /* RCOMP result register */
#define GDCRCKPICODE_ch(ch) Gz(0x0c14, ch) /* PI coding for DDR CLK pins */
#define GDCRCKLOGICDELAY_ch(ch) Gz(0x0c18, ch) /* Logic delay of 1 QCLK in CLK slice */
#define GDDLLFUSE_ch(ch) Gz(0x0c20, ch) /* Used for fuse download to the DLLs */
#define GDCRCLKDEBUGMUXCFG_ch(ch) Gz(0x0c3c, ch) /* Debug MUX control */
#define GDCRCMDDEBUGMUXCFG_Cz_S(ch) Gz(0x0e3c, ch) /* Debug MUX control */
#define CRCOMPOFST1_ch(ch) Gz(0x1810, ch) /* DQ, CTL and CLK Offset values */
#define GDCRTRAININGMOD_ch(ch) Gz(0x3000, ch) /* Data training mode control */
#define GDCRTRAININGRESULT1_ch(ch) Gz(0x3004, ch) /* Training results according to PI */
#define GDCRTRAININGRESULT2_ch(ch) Gz(0x3008, ch)
#define GDCRCTLRANKSUSED_ch(ch) Gz(0x3200, ch) /* Indicates which rank is populated */
#define GDCRCMDCOMP_ch(ch) Gz(0x3204, ch) /* COMP values register */
#define GDCRCMDCTLCOMP_ch(ch) Gz(0x3208, ch) /* COMP values register */
#define GDCRCMDPICODING_ch(ch) Gz(0x320c, ch) /* Command and control PI coding */
#define GDCRTRAININGMOD 0x3400 /* Data training mode control register */
#define GDCRDATACOMP 0x340c /* COMP values register */
#define CRCOMPOFST2 0x3714 /* CMD DRV, SComp and Static Leg controls */
/* MC per-channel registers */
#define TC_DBP_ch(ch) Cx(0x4000, ch) /* Timings: BIN */
#define TC_RAP_ch(ch) Cx(0x4004, ch) /* Timings: Regular access */
#define TC_RWP_ch(ch) Cx(0x4008, ch) /* Timings: Read / Write */
#define TC_OTHP_ch(ch) Cx(0x400c, ch) /* Timings: Other parameters */
#define SCHED_SECOND_CBIT_ch(ch) Cx(0x401c, ch) /* More chicken bits */
#define SCHED_CBIT_ch(ch) Cx(0x4020, ch) /* Chicken bits in scheduler */
#define SC_ROUNDT_LAT_ch(ch) Cx(0x4024, ch) /* Round-trip latency per rank */
#define SC_IO_LATENCY_ch(ch) Cx(0x4028, ch) /* IO Latency Configuration */
#define SCRAMBLING_SEED_1_ch(ch) Cx(0x4034, ch) /* Scrambling seed 1 */
#define SCRAMBLING_SEED_2_LOW_ch(ch) Cx(0x4038, ch) /* Scrambling seed 2 low */
#define SCRAMBLING_SEED_2_HIGH_ch(ch) Cx(0x403c, ch) /* Scrambling seed 2 high */
/* IOSAV Bytelane Bit-wise error */
#define IOSAV_By_BW_SERROR_ch(ch, y) CxLy(0x4040, ch, y)
/* IOSAV Bytelane Bit-wise compare mask */
#define IOSAV_By_BW_MASK_ch(ch, y) CxLy(0x4080, ch, y)
/*
* Defines the number of transactions (non-VC1 RD CAS commands) between two priority ticks.
* Different counters for transactions that are issued on the ring agents (core or GT) and
* transactions issued in the SA.
*/
#define SC_PR_CNT_CONFIG_ch(ch) Cx(0x40a8, ch)
#define SC_PCIT_ch(ch) Cx(0x40ac, ch) /* Page-close idle timer setup - 8 bits */
#define PM_PDWN_CONFIG_ch(ch) Cx(0x40b0, ch) /* Power-down (CKE-off) operation config */
#define ECC_INJECT_COUNT_ch(ch) Cx(0x40b4, ch) /* ECC error injection count */
#define ECC_DFT_ch(ch) Cx(0x40b8, ch) /* ECC DFT features (ECC4ANA, error inject) */
#define SC_WR_ADD_DELAY_ch(ch) Cx(0x40d0, ch) /* Extra WR delay to overcome WR-flyby issue */
#define IOSAV_By_BW_SERROR_C_ch(ch, y) CxLy(0x4140, ch, y) /* IOSAV Bytelane Bit-wise error */
/* IOSAV sub-sequence control registers */
#define IOSAV_n_SP_CMD_ADDR_ch(ch, y) LyCx(0x4200, ch, y) /* Special command address. */
#define IOSAV_n_ADDR_UPD_ch(ch, y) LyCx(0x4210, ch, y) /* Address update control */
#define IOSAV_n_SP_CMD_CTL_ch(ch, y) LyCx(0x4220, ch, y) /* Control of command signals */
#define IOSAV_n_SUBSEQ_CTL_ch(ch, y) LyCx(0x4230, ch, y) /* Sub-sequence controls */
#define IOSAV_n_ADDRESS_LFSR_ch(ch, y) LyCx(0x4240, ch, y) /* 23-bit LFSR state value */
#define PM_THML_STAT_ch(ch) Cx(0x4280, ch) /* Thermal status of each rank */
#define IOSAV_SEQ_CTL_ch(ch) Cx(0x4284, ch) /* IOSAV sequence level control */
#define IOSAV_DATA_CTL_ch(ch) Cx(0x4288, ch) /* Data control in IOSAV mode */
#define IOSAV_STATUS_ch(ch) Cx(0x428c, ch) /* State of the IOSAV sequence machine */
#define TC_ZQCAL_ch(ch) Cx(0x4290, ch) /* ZQCAL control register */
#define TC_RFP_ch(ch) Cx(0x4294, ch) /* Refresh Parameters */
#define TC_RFTP_ch(ch) Cx(0x4298, ch) /* Refresh Timing Parameters */
#define TC_MR2_SHADOW_ch(ch) Cx(0x429c, ch) /* MR2 shadow - copy of DDR configuration */
#define MC_INIT_STATE_ch(ch) Cx(0x42a0, ch) /* IOSAV mode control */
#define TC_SRFTP_ch(ch) Cx(0x42a4, ch) /* Self-refresh timing parameters */
#define IOSAV_ERROR_ch(ch) Cx(0x42ac, ch) /* Data vector count of the first error */
#define IOSAV_DC_MASK_ch(ch) Cx(0x42b0, ch) /* IOSAV data check masking */
#define IOSAV_By_ERROR_COUNT_ch(ch, y) CxLy(0x4340, ch, y) /* Per-byte 16-bit error count */
#define IOSAV_G_ERROR_COUNT_ch(ch) Cx(0x4364, ch) /* Global 16-bit error count */
#define PM_TRML_M_CONFIG_ch(ch) Cx(0x4380, ch) /* Thermal mode configuration */
#define PM_CMD_PWR_ch(ch) Cx(0x4384, ch) /* Power contribution of commands */
#define PM_BW_LIMIT_CONFIG_ch(ch) Cx(0x4388, ch) /* Bandwidth throttling on overtemp */
#define SC_WDBWM_ch(ch) Cx(0x438c, ch) /* Watermarks and starvation counter */
/* MC Channel Broadcast registers */
#define TC_DBP 0x4c00 /* Timings: BIN */
#define TC_RAP 0x4c04 /* Timings: Regular access */
#define TC_RWP 0x4c08 /* Timings: Read / Write */
#define TC_OTHP 0x4c0c /* Timings: Other parameters */
#define SCHED_SECOND_CBIT 0x4c1c /* More chicken bits */
#define SCHED_CBIT 0x4c20 /* Chicken bits in scheduler */
#define SC_ROUNDT_LAT 0x4c24 /* Round-trip latency per rank */
#define SC_IO_LATENCY 0x4c28 /* IO Latency Configuration */
#define SCRAMBLING_SEED_1 0x4c34 /* Scrambling seed 1 */
#define SCRAMBLING_SEED_2_LOW 0x4c38 /* Scrambling seed 2 low */
#define SCRAMBLING_SEED_2_HIGH 0x4c3c /* Scrambling seed 2 high */
#define IOSAV_By_BW_SERROR(y) Ly(0x4c40, y) /* IOSAV Bytelane Bit-wise error */
#define IOSAV_By_BW_MASK(y) Ly(0x4c80, y) /* IOSAV Bytelane Bit-wise compare mask */
/*
* Defines the number of transactions (non-VC1 RD CAS commands) between two priority ticks.
* Different counters for transactions that are issued on the ring agents (core or GT) and
* transactions issued in the SA.
*/
#define SC_PR_CNT_CONFIG 0x4ca8
#define SC_PCIT 0x4cac /* Page-close idle timer setup - 8 bits */
#define PM_PDWN_CONFIG 0x4cb0 /* Power-down (CKE-off) operation config */
#define ECC_INJECT_COUNT 0x4cb4 /* ECC error injection count */
#define ECC_DFT 0x4cb8 /* ECC DFT features (ECC4ANA, error inject) */
#define SC_WR_ADD_DELAY 0x4cd0 /* Extra WR delay to overcome WR-flyby issue */
/* Opportunistic reads configuration during write-major-mode (WMM) */
#define WMM_READ_CONFIG 0x4cd4 /** WARNING: Only exists on IVB! */
#define IOSAV_By_BW_SERROR_C(y) Ly(0x4d40, y) /* IOSAV Bytelane Bit-wise error */
#define IOSAV_n_SP_CMD_ADDR(n) Ly(0x4e00, n) /* Sub-sequence special command address */
#define IOSAV_n_ADDR_UPD(n) Ly(0x4e10, n) /* Address update after command execution */
#define IOSAV_n_SP_CMD_CTL(n) Ly(0x4e20, n) /* Command signals in sub-sequence command */
#define IOSAV_n_SUBSEQ_CTL(n) Ly(0x4e30, n) /* Sub-sequence command parameter control */
#define IOSAV_n_ADDRESS_LFSR(n) Ly(0x4e40, n) /* 23-bit LFSR value of the sequence */
#define PM_THML_STAT 0x4e80 /* Thermal status of each rank */
#define IOSAV_SEQ_CTL 0x4e84 /* IOSAV sequence level control */
#define IOSAV_DATA_CTL 0x4e88 /* Data control in IOSAV mode */
#define IOSAV_STATUS 0x4e8c /* State of the IOSAV sequence machine */
#define TC_ZQCAL 0x4e90 /* ZQCAL control register */
#define TC_RFP 0x4e94 /* Refresh Parameters */
#define TC_RFTP 0x4e98 /* Refresh Timing Parameters */
#define TC_MR2_SHADOW 0x4e9c /* MR2 shadow - copy of DDR configuration */
#define MC_INIT_STATE 0x4ea0 /* IOSAV mode control */
#define TC_SRFTP 0x4ea4 /* Self-refresh timing parameters */
/*
* Auxiliary register in mcmnts synthesis FUB (Functional Unit Block). Additionally, this
* register is also used to enable IOSAV_n_SP_CMD_ADDR optimization on Ivy Bridge.
*/
#define MCMNTS_SPARE 0x4ea8 /** WARNING: Reserved, use only on IVB! */
#define IOSAV_ERROR 0x4eac /* Data vector count of the first error */
#define IOSAV_DC_MASK 0x4eb0 /* IOSAV data check masking */
#define IOSAV_By_ERROR_COUNT(y) Ly(0x4f40, y) /* Per-byte 16-bit error counter */
#define IOSAV_G_ERROR_COUNT 0x4f64 /* Global 16-bit error counter */
#define PM_TRML_M_CONFIG 0x4f80 /* Thermal mode configuration */
#define PM_CMD_PWR 0x4f84 /* Power contribution of commands */
#define PM_BW_LIMIT_CONFIG 0x4f88 /* Bandwidth throttling on overtemperature */
#define SC_WDBWM 0x4f8c /* Watermarks and starvation counter config */
#define MAD_CHNL 0x5000 /* Address Decoder Channel Configuration */
#define MAD_DIMM_CH0 0x5004 /* Address Decode Channel 0 */
#define MAD_DIMM_CH1 0x5008 /* Address Decode Channel 1 */
#define MAD_DIMM_CH2 0x500c /* Address Decode Channel 2 (unused on SNB) */
#define MAD_ZR 0x5014 /* Address Decode Zones */
#define MCDECS_SPARE 0x5018 /* Spare register in mcdecs synthesis FUB */
#define MCDECS_CBIT 0x501c /* Chicken bits in mcdecs synthesis FUB */
#define CHANNEL_HASH 0x5024 /** WARNING: Only exists on IVB! */
#define MC_INIT_STATE_G 0x5030 /* High-level behavior in IOSAV mode */
#define MRC_REVISION 0x5034 /* MRC Revision */
#define PM_DLL_CONFIG 0x5064 /* Memory Controller I/O DLL config */
#define RCOMP_TIMER 0x5084 /* RCOMP evaluation timer register */
#define MC_LOCK 0x50fc /* Memory Controlller Lock register */
#define VTD1_BASE 0x5400 /* Base address for IGD */
#define VTD2_BASE 0x5410 /* Base address for PEG, USB, SATA, etc. */
#define PAIR_CTL 0x5418 /* Power Aware Interrupt Routing Control */
/* PAVP control register, undocumented. Different from PAVPC on PCI config space. */
#define MMIO_PAVP_CTL 0x5500 /* Bit 0 locks PAVP settings */
#define MEM_TRML_ESTIMATION_CONFIG 0x5880
#define MEM_TRML_THRESHOLDS_CONFIG 0x5888
#define MEM_TRML_INTERRUPT 0x58a8
#define MC_BIOS_REQ 0x5e00
#define MC_BIOS_DATA 0x5e04
#define MC_TURBO_PL1 0x59a0 /* Turbo Power Limit 1 parameters */
#define MC_TURBO_PL2 0x59a4 /* Turbo Power Limit 2 parameters */
#define SSKPD_OK 0x5d10 /* 64-bit scratchpad register */
#define SSKPD 0x5d14 /* 16bit (scratchpad) */
#define BIOS_RESET_CPL 0x5da8 /* 8bit */
/* PCODE will sample SAPM-related registers at the end of Phase 4. */
#define MC_BIOS_REQ 0x5e00 /* Memory frequency request register */
#define MC_BIOS_DATA 0x5e04 /* Miscellaneous information for BIOS */
#define SAPMCTL 0x5f00 /* Bit 3 enables DDR EPG (C7i) on IVB */
#define M_COMP 0x5f08 /* Memory COMP control */
#define SAPMTIMERS 0x5f10 /* SAPM timers in 10ns (100 MHz) units */
/* WARNING: Only applies to Sandy Bridge! */
#define BANDTIMERS_SNB 0x5f18 /* MPLL and PPLL time to do self-banding */
/** WARNING: Only applies to Ivy Bridge! */
#define SAPMTIMERS2_IVB 0x5f18 /** Extra latency for DDRIO EPG exit (C7i) */
#define BANDTIMERS_IVB 0x5f20 /** MPLL and PPLL time to do self-banding */
/*
* EPBAR - Egress Port Root Complex Register Block
*/